问题描述:

I'm learning C++ and I found a behavior I don't understand. If I write the following program in C:

#include <stdio.h>

int main() {

char question[] = "What is your name? ";

char answer[2];

printf(question);

scanf("%ls", answer);

printf("%s\n", answer);

return 0;

}

When I type a name longer than two bytes the answer is something gibberish, but even if I don't know exactly why, I know that something went wrong and it tried to recover.

Instead, if I write this C++ program (somewhat equivalent to the former):

#include <iostream>

using namespace std;

int main() {

char question[] = "What is your name? ";

char answer[2];

cout << question;

cin >> answer;

cout << answer << endl;

return 0;

}

I'd expect a similar behavior, since I declared answer as a char array and not a string (which can adjust its size dynamically). But when I type something very long, it is printed back as I entered it. An example:

$ ./test

What is your name? asdfa

asdfa

$ ./test

What is your name? sdhjklwertiuoxcvbnm

sdhjklwertiuoxcvbnm

So, what's going on here? As a secondary question, what happens in the C one, when I type something longer?

EDIT: Just to clarify, I know I can use std::string instead of char arrays (I had written it above ^^). I was interested in knowing why the programs exhibited that behavior. Now I know it's undefined behavior. Also, I corrected the error in the C program (scanf).

网友答案:

This is undefined behavior (UB):

scanf(answer);

scanf function will interpret the uninitialized content of answer as the format string, causing UB.

It should be like this:

scanf("%1s", answer);

Note that when you declare a character array of size 2, it means that it could fit a C string of length at most 1, because you need one character for null terminator.

Note that when you enter more than two characters for the name in your C++ program, you get undefined behavior too: writing past the end of the array is UB. Fortunately, it is very rare to need to read a string into a character array in C++, because the standard C++ library supplies a dynamically resizing class std::string, a much better choice for representing strings.

网友答案:

char answer[2]; means your array can contain only 2 characters. if you push more than that, the memory is overrun and it is undefined behavior. Either reserve enough space in the array, or better use std::string if using array is not mandatory. And you are taking input in wrong way as the other answer pointed out.

网友答案:

You cannot expect similar behaviour.

You can expect undefined behaviour in both cases: overrunning your memory buffer is undefined behaviour in both languages, so absolutely anything is allowed to happen.

网友答案:

char answer[2]; contains space for just 2 bytes. (1 byte + 1 NUL character in case of NUL terminated string)

In both C and C++ accessing data beyond the array size is undefined. So you should now ask why, how etc. You should just not do that.

Correct way to handle this undefined behaviour would be:

  • In C allocate enough space in memory (Or use fread not to read enough space the array can digest)
  • In C++, use std::string
相关阅读:
Top