Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!wuarchive!zaphod.mps.ohio-state.edu!samsung!uunet!mcsun!hp4nl!let.rug.nl!eoo From: eoo@let.rug.nl (Eize Oosting) Newsgroups: comp.lang.c Subject: Re: Arrays. Message-ID: <1711@gufalet.let.rug.nl> Date: 23 May 91 02:48:54 GMT References: <6466@gara.une.oz.au> Organization: Faculty of Arts, Groningen, The Netherlands Lines: 107 In article <6466@gara.une.oz.au> cfiddyme@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 > >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@let.rug.nl | Eize Oosting | \ __________ / \ ___________________________________________________ / \/ \/ \/ \/