Thread: writing/reading from file produces double results.

  1. #1
    eh ya hoser, got a beer? stumon's Avatar
    Join Date
    Feb 2003
    Posts
    323

    writing/reading from file produces double results.

    When getting input from the user and storing it into a struct, then writing that info to file using fwrite, it writes 2 of the same thing into the file.

    When searching (using fread) the description (string) member, it will find 2 entries with the same information. But when I search for the number (int) member, it will only find the one.

    Below is the add entry function and the 2 search functions (number and description). I pass the file pointer to each from main. There is also the output so you may see what I mean.

    Code:
    struct checkinfo
    {
    	int number;
    	char order[40];
    	double amount;
    	char desc[80];
    };
    
    void update_add(FILE *fPtr)
    {
    	struct checkinfo check;
    	char checknumtemp[4] = {'\0'}, tempResponce[1];
    	char tempamount[18] = {'\0'};
    	int userResponce;
    	
    	rewind(fPtr);
    	printf("Please enter the following information to add a new check.");
    	printf("? Check number: ");
    	gets(checknumtemp);
    	check.number = atoi(checknumtemp);
    
    	fseek(fPtr, (check.number - 100) * sizeof(struct checkinfo), SEEK_SET);
    	fread(&check, sizeof(struct checkinfo), 1, fPtr);
    	//if check number is not 0 (empty) ash user to overwrite or leave alone.
    
    	if (check.number != 0){
    		printf("Check information has already been entered!\n");
    		printf("Check\tPay to the Order of    \tAmount  \tDescription\n");
    		printf("%-1d\t%-23s\t%-8.2f\t%s\n\n", check.number, check.order, 
    											  check.amount, check.desc);
    		printf("Would you like to overwrite this entry?\n");
    		printf("1 - Yes\n2 - No ");
    		tempResponce[0] = getche();
    		userResponce = atoi(tempResponce);
    	}
    	//if user enters 1 to change, or the number is originally 0 (empty), use original
    	//user input for check number, and get info into struct for rest of members. then seek
    	//that position in file and write info. ***Seems like it saves it under the correct
    	//byte location according to fseek but it stores the information twice, debugger [MV C++]
    	//shows struct information being correct with only 1 set of entries per member.
    
    	if (userResponce == 1 || check.number == 0){
    		check.number = atoi(checknumtemp);
    		printf("? Pay to the Order: ");
    		gets(check.order);
    		printf("? Amount: ");
    		gets(tempamount);
    		check.amount = atof(tempamount);
    		printf("? Description: ");
    		gets(check.desc);
    		fseek(fPtr, (check.number - 100) * sizeof(struct checkinfo), SEEK_SET);
    		fwrite(&check, sizeof(struct checkinfo), 1, fPtr);
    	} else
    		printf("\n\nOriginal entry was saved.\n");
    }
    
    void search_check(FILE *fPtr)
    {
    	struct checkinfo check;
    	char checknumtemp[4] = {'\0'};
    	int searchNumber, searchFound = 0;
    	
    	rewind(fPtr);
    	printf("Enter the \"Check number\" to search for: ");
    	gets(checknumtemp);
    	searchNumber = atoi(checknumtemp);
    
    	while (!feof(fPtr) && searchFound == 0)
    	{
    		fread(&check, sizeof(struct checkinfo), 1, fPtr);
    
    		if (check.number == searchNumber){
    			printf("Check found!\n");
    			printf("Check\tPay to the Order of    \tAmount  \tDescription\n");
    			printf("%-1d\t%-23s\t%-8.2f\t%s\n", check.number, check.order, 
    												  check.amount, check.desc);
    			searchFound = 1;
    		}
    	}
    	if (searchFound == 0)
    		printf("\"Check number\" not found!\n");
    	printf("\n");
    }
    
    void search_description(FILE *fPtr)
    {
    	struct checkinfo check;
    	char desctemp[80] = {'\0'};
    	int searchFound = 0, temper = 0;
    	
    	rewind(fPtr);
    	printf("Enter the \"Description\" to search for: ");
    	gets(desctemp);
    
    	while (!feof(fPtr))
    	{              //read each byte location and put into struct check.
    		fread(&check, sizeof(struct checkinfo), 1, fPtr);
    		//compare user input with struct member '0' = exact match.
    		if (strcmp(desctemp, check.desc) == 0){
    			if (temper == 0){ //if this is first entry found, print title.
    				printf("Check found!\n");
    				printf("Check\tPay to the Order of    \tAmount  \tDescription\n");
    				temper = 1; //set so title does not print again.
    			}
    			printf("%-1d\t%-23s\t%-8.2f\t%s\n", check.number, check.order, 
    												  check.amount, check.desc);
    			searchFound = 1;
    		}
    	}
    	if (searchFound == 0)
    		printf("\"Description\" not found!\n");
    	printf("\n");
    }
    Here is the output I get after I enter 1 entry.

    Code:
    Please select from the options below.
            1) Search.
            2) Sort.
            3) Update.
            4) Exit.
    
            Selection: 3
    What would you like to do?
            1) Add entry.
            2) Delete entry.
            Selection: 1
    Please enter the following information to add a new check.
    ? Check number: 160
    ? Pay to the Order: Stumon
    ? Amount: 145.65
    ? Description: Blah Blah
    
    Please select from the options below.
            1) Search.
            2) Sort.
            3) Update.
            4) Exit.
    
            Selection: 1
    What would you like to search for?
            1) Check number.
            2) Pay to the Order.
            3) Amount.
            4) Description.
            Selection: 1
    Enter the "Check number" to search for: 140
    Check found!
    Check   Pay to the Order of     Amount          Description
    160     Stumon                  145.65          Blah Blah
    
    Please select from the options below.
            1) Search.
            2) Sort.
            3) Update.
            4) Exit.
    
            Selection: 1
    What would you like to search for?
            1) Check number.
            2) Pay to the Order.
            3) Amount.
            4) Description.
            Selection: 4
    Enter the "Description" to search for: Blah Blah
    Check found!
    Check   Pay to the Order of     Amount          Description
    160     Stumon                  145.65          Blah Blah
    160     Stumon                  145.65          Blah Blah
    P.S. By the way, the main function opens the file using "r+" because I have already written a program that will write the existing user information using "w" quickly and easily and save the file. This means there are not any repeat entries. There are about 10 entries at this point, but none with check number 160, that location should be blank because the previous program wrote 0 - 99 sizeof(struct ...) byte locations to {0, "", 0.0, ""}. Everything but those 10 locations about have 0's or blanks not garbage. Please email me if you would like the source to both programs to check any further information you will need in helping me. Thanks in advanced.

  2. #2
    eh ya hoser, got a beer? stumon's Avatar
    Join Date
    Feb 2003
    Posts
    323
    another P.S. If I do a search for check number, amount, pay to the order, or description to an entry that was put in by the first program, it will show only 1 entry. This only happens on entries I enter from this program. I did a search for Stumon and because I had 2 others with that name, it showed 4. first 2 were the other 2 from the original, and the last 2 were the same as this printed out.

  3. #3
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  4. #4
    eh ya hoser, got a beer? stumon's Avatar
    Join Date
    Feb 2003
    Posts
    323
    Thanks, I understand that now. I have another question though. When looking at the file i have been writing to. The information that was put in from the original program, which uses fseek and fwrite it stored in their respective byte locations in the file. The information is stored properly, check 100 is the first. However, when I change the search by check number to use fseek because the check numbers are stored in their respective byte locations (check.number - 100) * (sizeof(struct checkinfo), it will not find a entry I enter using the update_add function. it should save check 100 in byte location 0, It does not when I try to update. It will write the information I put in to the end of the file. Below is the source for that small program I mentioned that I use to originally store the information. Should I use a different way to open the file and not 'a+' in the original program?

    Code:
    int main(void)
    {
    	FILE *filePtr;
    	struct testinfo info = {0, "", 0.0, ""};
    	int i;
    	char tempnum[4] = {'\0'}, tempamount[20] = {'\0'};
    	
    	if ((filePtr = fopen("temp.dat", "w")) == NULL)
    		printf("File could not be opened.\n");
    	else {
    		for (i = 0; i <= 100; i++){ //temp write 100 entries to 0
    			fwrite(&info, sizeof(struct testinfo), 1, filePtr);
    		}
    		info.checknum = 1; //set to 1 only to enter the loop
    		while (info.checknum != 0)
    		{
    			printf("Enter the Checknum, Payto, Amount, and description. 0 to quit.\n");
    			printf("? ");
    			gets(tempnum);
    			info.checknum = atoi(tempnum);
    			if (info.checknum != 0){
    				printf("? ");
    				gets(info.payto);
    				printf("? ");
    				gets(tempamount);
    				info.amount = atof(tempamount);
    				printf("? ");
    				gets(info.description);
    				fseek(filePtr, (info.checknum - 100) * sizeof(struct testinfo), SEEK_SET);
    				fwrite(&info, sizeof(struct testinfo), 1, filePtr);
    			}
    		};
    	}
    	fclose(filePtr);
    	return 0;
    }
    It uses 'w' because this is temp information and I dont want there to be any other previous entries I have entered using the second program. The second program uses fopen with "a+" so I can rewrite the information without loosing any previous info loss.

    Thanks.

  5. #5
    eh ya hoser, got a beer? stumon's Avatar
    Join Date
    Feb 2003
    Posts
    323
    This is how I changed the search by check number function.

    Code:
    void search_check(FILE *fPtr)
    {
    	struct checkinfo check;
    	char checknumtemp[4] = {'\0'};
    	int searchNumber, searchFound = 0;
    	
    	rewind(fPtr);
    	printf("Enter the \"Check number\" to search for: ");
    	gets(checknumtemp);
    	searchNumber = atoi(checknumtemp);
    
    	fseek(fPtr, (searchNumber - 100) * sizeof(struct checkinfo), SEEK_SET);
    	fread(&check, sizeof(struct checkinfo), 1, fPtr);
    	printf("Check\tPay to the Order of    \tAmount  \tDescription\n");
    	printf("%-1d\t%-23s\t%-8.2f\t%s\n\n", check.number, check.order, 
    										  check.amount, check.desc);
    	printf("\n");
    }
    I have also noticed that if i search for amount that has info that was inputted with the original, it prints the check number correctly, if it finds something that was inputted with the update add function, it will print 0 for the check number. it does not seem to be fseeking to the correct location in the file.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. functions and passing data
    By redmondtab in forum C Programming
    Replies: 41
    Last Post: 09-21-2006, 12:04 PM
  2. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  3. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM
  4. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM