C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 03-31-2009, 09:47 PM   #1
Registered User
 
Join Date: Mar 2009
Posts: 6
Struct File and array problem Please help

Anyone knows why this code isn't working. the problem seems to be related to the size of the char arrays.

I am trying to read some data into a struct, write the struct to a file, close the file, read the data again and print it.

when I read and print the data again, it displays a lot of garbage characters.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>


struct clientInfo
{

	char name[25];
	char address[25];
	char telNumber[25];
	char attentionItem [25];
	char problemDescription[5];

};


int main()
{

	int i;
	const int size = 2;
	struct clientInfo data[size];
   struct clientInfo dat;
   FILE *clientFile;

   clientFile = fopen("clients.txt","w");

	for (i = 0; i < size; i++)
	{
      fflush(stdin);

		printf ("Please enter your name\n");
      gets (data[i].name);
		fflush(stdin);
		printf ("Please enter your address\n");
		gets (data[i].address);
		fflush(stdin);
		printf ("Please enter your telephone number\n");
		gets (data[i].telNumber);
		fflush(stdin);
		printf ("Please enter the item which aquires attention\n");
		gets (data[i].attentionItem);
		fflush(stdin);
		printf ("Please enter a description of the problem\n");
		gets (data[i].problemDescription);
		fflush(stdin);

   	fflush(stdin);
      fwrite(*data[i],sizeof(data[i]),1,clientFile);

   }//endfor

   fclose(clientFile);

   clientFile = fopen("clients.txt","r");

   while(!feof(clientFile))
   {
   	fread(&dat,sizeof(clientInfo),1,clientFile);

   	printf("name is %s\n",dat.name);
   	printf("address is %s\n",dat.address);
   	printf("telephone is %s\n",dat.telNumber);
      printf("attention is %s\n",dat.attentionItem);
   	printf("problem is %s\n",dat.problemDescription);

   }//end while

   fclose(clientFile);

   system("pause");

   return 0;

}//endmain
theprogrammer is offline   Reply With Quote
Old 03-31-2009, 11:05 PM   #2
Registered User
 
Join Date: Sep 2006
Posts: 3,157
You're mixing your output and input modes.

Use fprintf() for text mode, and you can use fscanf(), (or any other text mode file reader), to read the data back into your program.

Use fwrite() to write out data in binary mode, and use fread() to read it back into your program.

It's always good to be specific when you open files:

Not just mode "r" for reading. Either "rt" or "rb", please. Be specific, either text or binary. Don't leave it up to some global variable buried in a header file, somewhere.
Adak is offline   Reply With Quote
Old 04-01-2009, 12:16 AM   #3
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,336
Quote:
Originally Posted by Adak View Post
Not just mode "r" for reading. Either "rt" or "rb", please. Be specific, either text or binary. Don't leave it up to some global variable buried in a header file, somewhere.
rt is non-standard extention

r - is standard for text mode
rb is standard for binary mode.

To the OP:

Also fflush(stdin) is undefined - read FAQ. FAQ has samples how to get rid of junk in the input buffer using standard ways

gets should not be used - we have FAQ on the issue.


feof should not be used to control loops. FAQ explains why
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.
vart is offline   Reply With Quote
Old 04-01-2009, 12:17 AM   #4
Maz
Registered User
 
Join Date: Nov 2005
Posts: 150
Also, if you write the data in file member-by-member in binary, it is possible you'll be bitten by struct padding.
Maz is offline   Reply With Quote
Old 04-01-2009, 12:42 AM   #5
Registered User
 
Join Date: Sep 2006
Posts: 3,157
On what compiler do you get an error with file mode "rt"?

I use three compilers and have not noticed any problem with it.
Adak is offline   Reply With Quote
Old 04-01-2009, 12:48 AM   #6
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,336
Quote:
Originally Posted by Adak View Post
On what compiler do you get an error with file mode "rt"?

I use three compilers and have not noticed any problem with it.
And it makes this mode standard in your opinion?
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.
vart is offline   Reply With Quote
Old 04-01-2009, 01:00 AM   #7
Registered User
 
Join Date: Oct 2008
Location: TX
Posts: 1,453
Surprised that the compiler did not barf when it came across *data[i] as in.
Code:
fwrite(*data[i],sizeof(data[i]),1,clientFile); /* first arg should be a void pointer */
Instead of testing for feof() on the stream, a better test is to terminate if no. of items read is less than requested.
Code:
while(!feof(clientFile))  ??? 
itCbitC is offline   Reply With Quote
Old 04-01-2009, 02:47 AM   #8
Registered User
 
Join Date: Sep 2006
Posts: 3,157
Quote:
Originally Posted by vart View Post
And it makes this mode standard in your opinion?
If it works better, I tend to use it. Portability not only means the current compilers, but also the legacy compilers, if you have programs created for them.

I do, so I use what works best for me. I recommend it here, because a lot of the students are still using the legacy compilers.

Did you notice the conio.h include file, Vart? That's pretty much a gimme that he's using Turbo C, and my advice is targeted at Turbo C users (like me, sometimes).

Last edited by Adak; 04-01-2009 at 02:52 AM.
Adak is offline   Reply With Quote
Old 04-01-2009, 10:17 AM   #9
Registered User
 
Join Date: Mar 2009
Posts: 6
Mistake

it should be &data[i] and not *data[i] * I had changed it while attempting to debug the program. program seems to be fine. if I make all thee arrays sizes small. but gives problems when the array sizes are too large.

I really would like to continue using fwrite and gets.

gets because the name and address plus some other fields need to accept spaces.
fwrite because the struct is much larger than in the code I cut it down to help focus on the problem. And I do not want to have to use individual fprintf and fscanf statements for each field in the struct. Additionally I think fprintf and fscanf has problems with reading and writing spaces.

The first field is always fine. I might end up with a problem on the secord third fourth or fifth to the last field.

Thanks for all the replies
theprogrammer is offline   Reply With Quote
Old 04-01-2009, 12:18 PM   #10
Registered User
 
Join Date: Mar 2009
Posts: 6
Half Solution

I read the faq's that vart suggested on fflush, feof, and fgets. I made the necessary changes I also am now reading in binary mode. the only effect now is that it is ony printing three characters from the string.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

#define size 2

struct clientInfo
{

	char name[25];
	char address[25];
	char telNumber[25];
	char attentionItem [25];
	char problemDescription[6];

};


int main()
{

	int i,ch;
	struct clientInfo data[size];
   struct clientInfo dat;
   FILE *clientFile;

   clientFile = fopen("clients.txt","wb");

	for (i = 0; i < size; i++)
	{

		printf ("Please enter your name\n");
      fgets (data[i].name,sizeof(sizeof(char) * 25),stdin);
		//fflush(stdin);
      while ((ch = getchar()) != '\n' && ch != EOF);
		printf ("Please enter your address\n");
		fgets (data[i].address,sizeof(sizeof(char) * 25),stdin);
		//fflush(stdin);
      while ((ch = getchar()) != '\n' && ch != EOF);
		printf ("Please enter your telephone number\n");
		fgets (data[i].telNumber,sizeof(sizeof(char) * 25),stdin);
		//fflush(stdin);
      while ((ch = getchar()) != '\n' && ch != EOF);
		printf ("Please enter the item which aquires attention\n");
		fgets (data[i].attentionItem,sizeof(sizeof(char) * 25),stdin);
      while ((ch = getchar()) != '\n' && ch != EOF);
		//fflush(stdin);
		printf ("Please enter a description of the problem\n");
		fgets (data[i].problemDescription,sizeof(sizeof(char) * 6),stdin);
      while ((ch = getchar()) != '\n' && ch != EOF);

      fwrite(&data[i],sizeof(data[i]),1,clientFile);

   }//endfor

   fclose(clientFile);

   clientFile = fopen("clients.txt","rb");

   while(fread(&dat,sizeof(struct clientInfo),1,clientFile) != 0)
   {
   	printf("name is %s\n",dat.name);
   	printf("address is %s\n",dat.address);
   	printf("telephone is %s\n",dat.telNumber);
      printf("attention is %s\n",dat.attentionItem);
   	printf("problem is %s\n",dat.problemDescription);

   }//end while

   fclose(clientFile);

   system("pause");

   return 0;

}//endmain
Why is it only printing three characters from each string

for example if I entered Michelle for a name it gives me "Mic" only

Thanks in advance
theprogrammer is offline   Reply With Quote
Old 04-01-2009, 02:08 PM   #11
Registered User
 
Join Date: Sep 2008
Posts: 53
Code:
PHP Code:
#define size 2 
you only allow it too using fgets this way.
PHP Code:
for (0sizei++)     {         printf ("Please enter your name\n");       fgets (data[i].name,sizeof(sizeof(char) * 25),stdin); 
here is how i use fgets and i am not sure if am doing it right either but it reads the specified max input and prints it out.
PHP Code:
#include <stdio.h> int main(int argcchar** argv) {     char str[200];           fgets(str,(sizeof str),stdin);          printf("%s\n",str);         return 0; } 
you have only allowed it to read the defined 2 bytes as maxsize plus the extra character from the increment of i++ .also
PHP Code:
 (sizeof char 
) is one byte exactly. hope it helps. i am newbie and i have really bad eyesight so apology if i missed anything or made any mistakes.
cmay is offline   Reply With Quote
Old 04-01-2009, 02:34 PM   #12
CSharpener
 
vart's Avatar
 
Join Date: Oct 2006
Posts: 5,336
in general fgets with arrays is used like:

Code:
char buf[25];
if(fgets(buf,sizeof buf, fp))
{
   /* do something with buf */
}
your case is no different...

Code:
fgets (data[i].problemDescription,sizeof(data[i].problemDescription),stdin);
note that after EOF is reached - nothing will be read from the stream - so you should not continue your input after that
__________________
If I have eight hours for cutting wood, I spend six sharpening my axe.
vart is offline   Reply With Quote
Old 04-01-2009, 02:48 PM   #13
Registered User
 
Join Date: Oct 2008
Location: TX
Posts: 1,453
There is really no use for the while loop below:
Code:
while ((ch = getchar()) != '\n' && ch != EOF);   /* unnecessary imo */
fread() should terminate when no. of items read is not equal to 1 as in:
Code:
while(fread(&dat,sizeof(struct clientInfo),1,clientFile) == 1)

Last edited by itCbitC; 04-01-2009 at 02:55 PM.
itCbitC is offline   Reply With Quote
Old 04-01-2009, 05:59 PM   #14
Registered User
 
Join Date: Mar 2009
Posts: 6
Thumbs up Thanks every one

The reason for the while loop is to clean out the input stream as suggested in the faq instead of using fflush(stdin) however I removed them and the code still works.

Thanks a lot to everyone
Thanks vart for making me read the faqs they were very enlightening.
cmay your suggestion finally got my code working.

ItCbitC thanks for all your suggestion.

Thanks a lot I can't say thanks enough to you guys.

Here is the modified and working code

Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

#define size 2

struct clientInfo
{

	char name[25];
	char address[25];
	char telNumber[25];
	char attentionItem [25];
	char problemDescription[200];

};


int main()
{

	int i;
	struct clientInfo data[size];
   struct clientInfo dat;
   FILE *clientFile;

   clientFile = fopen("clients.txt","wb");

	for (i = 0; i < size; i++)
	{

		printf ("Please enter your name\n");
      fgets (data[i].name,sizeof(data[i].name),stdin);

		printf ("Please enter your address\n");
		fgets (data[i].address,sizeof(data[i].name),stdin);

		printf ("Please enter your telephone number\n");
		fgets (data[i].telNumber,sizeof(data[i].name),stdin);

		printf ("Please enter the item which aquires attention\n");
		fgets (data[i].attentionItem,sizeof(data[i].name),stdin);

      printf ("Please enter a description of the problem\n");
		fgets (data[i].problemDescription,sizeof(data[i].name),stdin);

      //write information to file
      fwrite(&data[i],sizeof(data[i]),1,clientFile);

   }//endfor

   fclose(clientFile);

   clientFile = fopen("clients.txt","rb");

   while(fread(&dat,sizeof(struct clientInfo),1,clientFile) == 1)
   {
   	printf("name is %s\n",dat.name);
   	printf("address is %s\n",dat.address);
   	printf("telephone is %s\n",dat.telNumber);
      printf("attention is %s\n",dat.attentionItem);
   	printf("problem is %s\n",dat.problemDescription);

   }//end while

   fclose(clientFile);

   system("pause");

   return 0;

}//end main
theprogrammer is offline   Reply With Quote
Old 04-01-2009, 08:34 PM   #15
Registered User
 
caroundw5h's Avatar
 
Join Date: Oct 2003
Posts: 719
Quote:
If it works better, I tend to use it. Portability not only means the current compilers, but also the legacy compilers
sounds like "quick it compiles! ship it!" lol. Adak, round here we emphasize ISO C, code thats guranteed to work across pretty much all platforms.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
what functions are you calling with conio.h programmer, i may have overlooked it but i don't see any reason in your code for it. again, i may have missed it, but let me know.


Quote:
There is really no use for the while loop below:
Code:

while ((ch = getchar()) != '\n' && ch != EOF); /* unnecessary imo */
you could make it even more compact
Code:
#define FLUSH while ( (getchar() ! = '\n') )
and then call FLUSH whenever you want to clean out the buffer.

Code:
 fclose(clientFile);

   system("pause");
you should check the return value of fclose to make sure that your file closed properly, there could be any number of reasons it didn't and then you shut down your program. Also your code may not be mission critical but try to get into the habit of writing portable, clean C code according to the std regardless of what is said other wise - and avoid using system("pause")
__________________
When the concrete cases are understood the abstractions are readily made
caroundw5h is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with file and array paok C Programming 5 05-01-2008 04:19 AM
File I/O problem for dynamically allocated struct array veecee C++ Programming 2 05-05-2006 09:28 PM
Unknown Memory Leak in Init() Function CodeHacker Windows Programming 3 07-09-2004 09:54 AM
Passing pointers between functions heygirls_uk C Programming 5 01-09-2004 06:58 PM
what does this mean to you? pkananen C++ Programming 8 02-04-2002 03:58 PM


All times are GMT -6. The time now is 11:31 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22