1

Below is a program that asks the user to type in a name, and then prints out the name one letter at a time, eventually producing the whole name. I have two versions of the program. The one below does a strange thing: if I type in something like jkljljkliunionnklsaa , it will produce only jkljljkl.

But if I restrict char name[40], and then type in the same name, the program shows the whole name. What have I done wrong in the program that doesn't allow it to produce the whole name?

    #include <stdio.h>
    #include <string.h>

    int main (void)
    {
        int i, s;
        char name[s];

        printf ("Type a name:  ");
        scanf ("%s", name);

        for ( i = 0; i < strlen(name); i++)
        {
            printf ("%c", name[i]); // print the i-th character of name
        }
        printf("\n");
     }
surajs1n
  • 1,493
  • 6
  • 23
  • 34
Ducol
  • 175
  • 1
  • 11
  • First of all, **NEVER** write anything like `scanf("%s", ...)`. That will read as many non-whitespace characters as the user enters into your array, which is not infinitely large. If your name array is 10 characters long and the user enters a 20 character word, then your program will crash or worse. By worse I mean a malicious user could take control of your program and run their own code, in this case as a trivial stack-based buffer overflow. The proper way to read in user input as strings is using `fgets()`. Replace your code with `fgets(name, sizeof(name), stdin);`. That will read a line. – C0deH4cker Aug 26 '15 at 15:23
  • Thank you. I am at the very first step of learning programming. I still have to learn functions you suggest. Happy to do that. Do I understand correctly that in case I use scanf I should alway restrict the number of possible entries, as I did with name[40]? – Ducol Aug 26 '15 at 15:32

2 Answers2

2
 int i, s;
 char name[s];

This is undefined behavior (in ISO C lingo; anything may happen, even something you might expect), since s is not initialized. Unlike the wording of your question suggests, an uninitialized variable as the array size does not mean nonrestricted size. It means program bug. :-)

s might happen to be 0 or 10 or -136186732, so you might or might not have a character array big enough to store some characters.

It will start working again with

 int i, s = 40;

To clarify, C does not have automatically growing or self-adapting arrays. If you need to allocate or resize arrays at run-time, you need to use malloc() and realloc().

Jens
  • 69,818
  • 15
  • 125
  • 179
  • Thank you. I wanted to use initially undefined array because no one knows how long names can be :) But negative values like -xxxx seem to be irrelevant - I am using char variables, not numbers; is it possible for programs to get negative chars? – Ducol Aug 26 '15 at 15:35
  • @Ducol `s` is not a char, it's an `int`, so it can be negative. The ISO C Standard says that the signedness of the `char` type is implementation-defined, so yes, there can be `char` values that are less than zero if that implementation has a signed `char` type. – Jens Aug 26 '15 at 15:51
0

See in your first version you didn't specify the size of the character array and you left it as name[s], where s is an integer initialized with garbage value.

Whereas, in the second case you made it as name[40] which technically speaking can hold up-to 39 characters long string. (39. Think Why???)

surajs1n
  • 1,493
  • 6
  • 23
  • 34
  • I am happy that I know why :) because it all starts from 0, hence 0 - 39 will be 40 chars. As to name [s], that was my goal. Given it is an incorrect approach, I am trying to find a way (if it exists) not to restrict the amount of letters entered by the user. – Ducol Aug 26 '15 at 15:35
  • Yes, there is an approach but is bit complex. check this out http://stackoverflow.com/questions/16870485/how-can-i-read-an-input-string-of-unknown-length. Here , file name is `stdin` means it is taking input from the console instead of any file. – surajs1n Aug 26 '15 at 16:02