0

I can't understand why char *ptr = new char[7] would not truncate an input of data bigger than 7 characters. Also why eighter char c[7] would let me input more than 6 characters (but giving error when attributing it a literal value of more than 6 characters).

Doing it with malloc function seems a little bit to hard for me for a moment, this is why i prefer not to use it. I would prefer for the moment not to use it.

char qs[7] = "1234567"; //error too many

char qs2[7];
cin >> qs2;             //input 123456789
cout << qs2;            //out same as input, expecting 123456

char *qs3 = new char[7];
cin >> qs3;             //input 123456789
cout << qs3;            //out same as input, expecting 123456
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Cătălina Sîrbu
  • 1,253
  • 9
  • 30
  • 5
    It's undefined behavior, and that doesn't guarantee any particular outcome. It might print `123456789`, it might print `123456`, it might print something else, it might hang, crash or do something entirely different. Most likely it will just corrupt your stack by overwriting something else, such as a stack pointer, which may or may not crash the program. If I run your program in Visual Studio with `123456789` for the input, it crashes. – Blaze Nov 07 '19 at 12:15
  • How could i be sure that after pressing `enter` from the console, my value will be strictly 6 chars long ? – Cătălina Sîrbu Nov 07 '19 at 12:16
  • Reading into a variable `until` a `counter` set to 6 will be reached? – Cătălina Sîrbu Nov 07 '19 at 12:17
  • @MarcStröbel but it still let me input more than one character – Cătălina Sîrbu Nov 07 '19 at 12:21
  • "How could i be sure that after pressing enter from the console, my value will be strictly 6 chars long ?" You can't, which is why `char qs2[7]; cin >> qs2` is a bad idea – Caleth Nov 07 '19 at 12:22

3 Answers3

7

The input stream, currently, only takes a pointer as an argument. Therefore it cannot know the size of the buffer that it fills. Therefore it cannot know whether it should truncate or not. Reading a string longer than the buffer will cause the buffer to overflow, and behaviour of the program will be undefined. Don't do it.

Since C++20, the array operand is passed by reference, and the operation does know the size and will truncate the input. This won't help in the case of qs3 however, since it is only a pointer rather than an array.

Instead, you can use:

std::cin.get(qs3, 6);
qs3[6] = '\0';

To ensure that no more characters are read than fit the buffer.

Or if you prefer to not truncate input, then you can read into std::string.


Doing it with malloc function seems a little bit to hard for me for a moment, this is why i prefer not to use it.

Good. It wouldn't solve your problem, and there is no need to use it, nor is there any advantage to using it either.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

The both code snippets

char qs2[7];
cin >> qs2;             //input 123456789
cout << qs2;            //out same as input, expecting 123456

char *qs3 = new char[7];
cin >> qs3;             //input 123456789
cout << qs3;            //out same as input, expecting 123456

have undefined behavior. The memory beyond the allocated arrays is overwritten. The consequence can be of any kind.

Consider the following demonstrative program.

#include <iostream>

int main() 
{
    char gs1[7] = "123456";
    char gs2[7];
    char gs3[7] = "ABCDEF";

    std::cin >> gs2;

    std::cout << '\n';

    std::cout << gs1 << '\n';
    std::cout << gs2 << '\n';
    std::cout << gs3 << '\n';

    return 0;
}

If to enter

1234567

then the program output might look like

123456
1234567

As you can see the string "ABCDEF" was not outputted. It is the result of that the terminating zero '\0' that was appended to the array gs2 after this statement

    std::cin >> gs2;

overwrites the first character of the array gs3. Now it content looks like

{ '\0', 'B', 'C', 'D', 'F', '\0' }

So as the first element of the array is the terminating zero then the empty string was being outputted in this statement

    std::cout << gs3 << '\n';
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

The C-strings are zero-terminated, that mean you should always allocate buffer with size string length + 1.

char qs[7] = "1234567"; //error too many

In statically allocated buffers it is obvious for the compiler that your buffer does not have space for terminating zero. This should be char qs[8].

In both other examples, the operator takes pointer to buffer as argument and there is no way for it to know how large it is. It just fill it until the end of input. You get classic buffer overrun situation, and you are lucky that there is nothing important out there (after the buffer boundaries).

Nanev
  • 106
  • 7