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

int main()
{
    int i;
    char a[10];
    for(i=0;i<10;i++)
    {
        scanf("%s",a);// >how this line is working in memory.
    }
    return 0;
}

In the above code, I would like to know how the string is saved in memory, since I have initialised it as a 1D character array, but does the array work as a list of strings, or a single string? Why?

BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70

5 Answers5

5

In C, a string is a sequence of character values terminated by a 0-valued character - IOW, the string "Hello" is represented as the character sequence 'H', 'e', 'l', 'l', 'o', 0. Strings are stored in arrays of char (or wchar_t for wide strings):

char str[] = "Hello";

In memory, str would look something like this:

     +---+
str: |'H'| str[0]
     +---+
     |'e'| str[1]
     +---+
     |'l'| str[2]
     +---+
     |'l'| str[3]
     +---+
     |'o'| str[4]
     +---+
     | 0 | str[5]
     +---+

It is possible to store multiple strings in a single 1D array, although almost nobody does this:

char strs[] = "foo\0bar";

In memory:

      +---+
strs: |'f'| strs[0]
      +---+
      |'o'| strs[1]
      +---+
      |'o'| strs[2]
      +---+
      | 0 | strs[3]
      +---+
      |'b'| strs[4]
      +---+
      |'a'| strs[5]
      +---+
      |'r'| strs[6]
      +---+
      | 0 | strs[7]
      +---+

The string "foo" is stored starting at strs[0], while the string "bar" is stored starting at strs[4].

Normally, to store an array of strings, you'd either use a 2D array of char:

char strs[][MAX_STR_LEN] = { "foo", "bar", "bletch" };

or a 1D array of pointers to char:

char *strs[] = { "foo", "bar", "bletch" };

In the first case, the contents of the string are stored within the strs array:

      +---+---+---+---+---+---+---+
strs: |'f'|'o'|'o'| 0 | ? | ? | ? |
      +---+---+---+---+---+---+---+
      |'b'|'a'|'r'| 0 | ? | ? | ? |
      +---+---+---+---+---+---+---+
      |'b'|'l'|'e'|'t'|'c'|'h'| 0 |
      +---+---+---+---+---+---+---+

In the second, each strs[i] points to a different, 1D array of char:

      +---+                 +---+---+---+---+
strs: |   | strs[0] ------> |'f'|'o'|'o'| 0 |
      +---+                 +---+---+---+---+
      |   | strs[1] ----+
      +---+             |   +---+---+---+---+
      |   | strs[2] -+  +-> |'b'|'a'|'r'| 0 |
      +---+          |      +---+---+---+---+
                     |
                     |      +---+---+---+---+---+---+---+
                     +----> |'b'|'l'|'e'|'t'|'c'|'h'| 0 |
                            +---+---+---+---+---+---+---+

In your code, a can (and is usually intended to) store a single string that's 9 characters long (not counting the 0 terminator). Like I said, almost nobody stores multiple strings in a single 1D array, but it is possible (in this case, a can store 2 4-character strings).

John Bode
  • 119,563
  • 19
  • 122
  • 198
2
char a[10];

You've allocated 10 bytes of the stack for a. But right now, it contains garbage because you never gave it a value.

Scanf doesn't know any of this. All it does is copy bytes from the standard input into a, ignorant of its size.

And why are you doing a loop 10 times? You will overwrite a each loop iteration, so you'll only have the value from the final time.

lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
2

A string is per definition a null-terminated character array. So every character array becomes a string as soon as it contains a \0 somewhere, defining the end of that string.

In memory the string is just a bunch of bytes laying (for simplicity but not necessarily) in sequence. Take the string "Hello" for example

+---+---+---+---+---+---+
| H | e | l | l | o | \0|  
+---+---+---+---+---+---+

Your array char a[10] is pointing to the beginning of such a memory location ('H' in the example) with enough space to store 10 characters. By using scanf you are storing an string (character sequence + terminating \0) in that buffer (over and over again). scanf stores the characters in there and adds a terminating \0 to the element after the last one written to. This allows you to safely store any character sequence that is at most 9 characters long, since the 10th character needs to be the \0

muXXmit2X
  • 2,745
  • 3
  • 17
  • 34
1

You are over-writing same buffer in loop 10 times, which means buffer will contain data entered in last reading and previous 9 strings will be lost.

Also entering more than 9 characters would cause buffer overflow which would invoke undefined behavior.

You should limit number of characters scanned from input buffer and then clear the rest of the buffer. (Not fflush(stdin);)

scanf("%9s",a);

Does a 1D array work as a list of strings, or a single string?

If its terminated with null character then yes, its string, like this. And a is the address of first element.

+---+---+---+---+---+---+----+
| S | t | r | i | n | g | \0 | 
+---+---+---+---+---+---+----+
  a  a+1 a+2

And if you pass this array ie. to printf(), he will print all characters until he reach \0.

If you would like to read list of strings, you have to declare 2D array or pointer-to-pointer-to-char and allocate enough memory for pointers.

int c;
char a[10][10];
for(i=0;i<10;i++)
{
    scanf("%9s",a[i]);
    while ((c = getchar()) != '\n' && c != EOF) ;
}
kocica
  • 6,412
  • 2
  • 14
  • 35
1

Does a 1D array work as a list of strings, or a single string?

quite broad question.

char a[10]; declared table a which has a size of 10 the char elements

char *a[10]; declared table a which has a size of 10 char * elements which can possible point to the string (when you allocate memory for it and copy the valid C string)

In your code: 'scanf("%s",a);' a means the address of the first element of the array. So scanf writes data there, every time overwriting the previous content. If your scanf-ed input will need more 10 elements (including trailing 0) to be stored, you will get an UB and very possible SEGFAUT

0___________
  • 60,014
  • 4
  • 34
  • 74