-2

The problem is simple, the code below does not work. it says Process finished with exit code -1073740940 (0xC0000374). Removing ampersand does not change anything.

int main(){
    string x;
    scanf("%s",&x);
    cout << x;
}
giusti
  • 3,156
  • 3
  • 29
  • 44
  • Use c-like strings or, **better**, use `cin` instead. –  Sep 07 '19 at 21:01
  • I know about `cin`, but now want to figure out what is wrong with that. I've noticed that it is faster than `cin`, thus better for competitive programming. –  Sep 07 '19 at 21:03
  • How can I use c-like strings? –  Sep 07 '19 at 21:05
  • Did you try `std::ios_base::sync_with_stdio (false);`? https://stackoverflow.com/questions/5406935/reading-a-string-with-scanf –  Sep 07 '19 at 21:06
  • This does not fix it. –  Sep 07 '19 at 21:08
  • What doesn't fix what? –  Sep 07 '19 at 21:16
  • I mean, it does not change anything. –  Sep 07 '19 at 21:20
  • 4
    Why did you think it would work? Which reference material or piece of documentation told you that it would work? Who explained that you could overwrite a `std::string` using a C library function? They were wrong. – Lightness Races in Orbit Sep 07 '19 at 21:23
  • Not syncing with C stdio is like releasing the handbrake on C++ IO. If you don't need this synchronization, that is. Another advise is to turn on warnings when compiling. Most compilers would have told you that the code is wrong. – Ulrich Eckhardt Sep 08 '19 at 06:33
  • 1
    Possible duplicate of [Read C++ string with scanf](https://stackoverflow.com/questions/20165954/read-c-string-with-scanf) – giusti Sep 09 '19 at 17:21
  • Consider accepting an answer if it helped you. – Daniel Mar 17 '20 at 15:12

5 Answers5

2

scanf() with the %s format specifier reads bytes into a preallocated character array (char[]), to which you pass a pointer.

Your s is not a character array. It is a std::string, a complex object.

A std::string* is not in any way the same as a char*. Your code overwrites the memory of parts of a complex object in unpredictable ways, so you end up with a crash.

Your compiler should have warned about this, since it knows that a char* is not a std::string*, and because compilers are clever and can detect mistakes like this despite the type-unsafe nature of C library functions.

Even if this were valid via some magic compatibility layer, the string is empty.

Use I/O streams instead.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

You cannot pass complex objects through the ... operator of printf/scanf. Many compilers print a warning for that.

scanf requires a pointer of type char* pointing to sufficient storage for an argument of %s. std::string is something completely different.

In C++ the iostream operators are intended for text input and output.

cin >> x;

will do the job.

You should not use scanf in C++. There are many pitfalls, you found one of them.

Another pitfall: %s at scanf is almost always undefined behavior unless you you really ensure that the source stream can only contain strings of limited size. In this case a buffer of char buffer[size]; is the right target. In any other case you should at least restrict the size of the string to scan. E.g. use %20s and of course a matching char buffer, char buffer[21];in this case. Note the size +1.

Marcel
  • 1,688
  • 1
  • 14
  • 25
0

You should use cin. But if you want to use scanf() for whatever reason and still manipulate your strings with std::string, then you can read the C-string and use it to initialize your C++ string.

#include <iostream>
#include <cstdio>
#include <string>

using std::cout;
using std::string;

int main()
{
    char c_str[80];

    scanf("%s", c_str);
    string str(c_str);

    cout << str << "\n";
}
giusti
  • 3,156
  • 3
  • 29
  • 44
0

If you want to use strings, use cin (or getline).

string s;
cin>>s;   //s is now read

If you want to use scanf, you want to have a char array (and don't use &):

char text[30];
scanf("%s", text); //text is now read
Daniel
  • 7,357
  • 7
  • 32
  • 84
0

You can use char[] instead of string

include <iostream>
using namespace std;
int main()
{
  char tmp[101];
  scanf("%100s", tmp);
  cout << tmp;
}
Nijin P J
  • 1,302
  • 1
  • 9
  • 15