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