Arrays.

Eize Oosting eoo at let.rug.nl
Thu May 23 12:48:54 AEST 1991


In article <6466 at gara.une.oz.au> cfiddyme at gara.une.oz.au (Kith Kanan) writes:
>
> hi,
>     I'm new to C and have been trying out a few things and have come up with
> a problem. In the code below I am reading a series of three digit numbers
> from a file and storing them as strings in a 2-d array.When I print them out
> strange things happen. Can someone please tell me what is causing this and how
> do I prevent it. Also when I replace the fscanf function with fgets() i get
> errors. Why?
>                                 Thanks
>                                            Chris.
>
>#include <stdio.h>
>
>main()
>{
>   char array[10][3];
>   char s[3];
>   FILE *input,*fopen();
>   int i = 0;
>
>   input = fopen("inarray","r");
>   while(!feof(input))  {
>      fscanf(input,"%s\n",s);
>      strcpy((char *) array[i],s);
>      i++;
>    }
>   for(i=0;i<=9;i++)
>     fprintf(stdout,"%s\n",array[i]);
>}
>
> This is the output of the program.The input file is just the first three
> digit's of each line.
>
>229657659312999867555664811109
>657659312999867555664811109
>659312999867555664811109
>312999867555664811109
>999867555664811109
>867555664811109
>555664811109
>664811109
>811109
>109

This is very simple, your subarrays have only three chars, however a real
C string consists of chars terminating with a '\0' (null-char). You do not have
room for these, so when you read a 3 digit string into one element, it's
null-char is put in the first field of the next element (arrays are one block
of memory). This null-char however is overwritten by the next read into THIS
field. The only dangerous situation is your read, because that null-char is
put into a dummy byte (because the next var 's' must be word-aligned). You 
must NOT read bigger numbers than 3 digits with this code, or else you
will overwrite the 'input' var. Consider what happens then.

I will try to graphisize this:

char array[10][3] is a block of 30 bytes, and after that you have s etc:

  0   1   2   3   4   5   6   7   8   9    s    input     i
+---+---+---+---+---+---+---+---+---+---++---+-+--------++--+
|   |   |   |   |   |   |   |   |   |   ||   | |  ptr   ||  |
+---+---+---+---+---+---+---+---+---+---++---+-+--------++--+
                                              ^ 
                                              This is a dummy byte to align
                                              the input var on a word-boundary.

After your first read, s contains '229', however its null-char lies beyond
the memory of 's'. Then you copy this to array[0]. array[0] now contains the
number and the null-char is in array[1].  

  0   1   2
+---+---+---
|229|o  |  ..
+---+---+---

Then you do the second read and copy this to array[1]:

  0   1   2   3
+---+---+---+---
|229|657|o  |  ..
+---+---+---+---

As you can guess, after 10 reads, your array is completely filled with only
digits and the null-char is located at the first byte of 's'. When you
are going to printf() the numbers, printf() searches each time for the 
null-char as the terminator. That's why you get the printf() always producing
this large numbers (strings).

THE SOLUTION: 

Make your arrays 4 digits long. Both array must be [10][4] and s must be [4].
When you are going to read (or copy) strings, ALWAYS have room for this extra
character. You don't see it, but it's there!

Hope this helps!

  /\__________/\   /\___________________________________________________/\
 /              \ /                                                       \
|   Letteren-    |  Marvin Minsky once defined Artificial Intelligence as: |
|   Faculteit    |   '... the science of making machines do things that    |
| R.U. Groningen |   would require intelligence if done by men'.           |
| The Netherlands|                                                         |
|                |  Does this include formatting a floppy?                 |
| eoo at let.rug.nl |                                           Eize Oosting  |
 \  __________  / \  ___________________________________________________  /
  \/          \/   \/                                                   \/



More information about the Comp.lang.c mailing list