fread() condition problem

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

32 Replies - 1281 Views - Last Post: 13 May 2013 - 05:45 AM Rate Topic: -----

#1 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

fread() condition problem

Posted 06 May 2013 - 06:25 AM

Hi. I'm trying to scan in a customer ID and then search a binary file, containing customer info, for the matching ID. The program is then meant to print out the customers details. However there's something wrong with my fread condition and I don't know what it is. The if statement is always satisfied and thus the else statement is never executed. I've attached the customers.bin file if anyone needs it. All help much appreciated!

void search(void)
{
	struct customer
	{
		int id;
		char first_name[11];
		char surname[21];
		int age;
		char gender;
		char address[50];
	};
	
	struct customer cus;
	FILE *fp;
	int offset;
	int answer;
	
	fp = fopen("customers.bin", "rb" );
	
	printf("\nEnter a user ID to display their information: ");
	scanf("%d",&answer);

	offset = (answer - 1) * sizeof(struct customer);
	fseek(fp, offset, 0);

	if((fread(&cus,sizeof(struct customer),1,fp)) != 1)
	{
		printf("\nError in reading file");
	}
	
	else
	{
		printf( "\nID: %d\nName: %s %s\nAge :%d\nGender: %c\nAddress: %s",
				cus.id, cus.first_name,cus.surname,cus.age,cus.gender, cus.address);
	}
}


Is This A Good Question/Topic? 0
  • +

Replies To: fread() condition problem

#2 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 06:40 AM

I see several places where your program could fail. You should be checking the return values of several functions. The first function to check is the fopen() function, did the file actually open correctly? The next place is the fseek() call, did it succeed? Next what value did your fread() actually return? Also all three of these functions will set the ferror error indicator if they fail and you can use perror() to help determine the actual cause of the failure.

Also I don't see your input file. You'll probably need to change the file extension to .txt in order to post as an attachment.

Jim
Was This Post Helpful? 0
  • +
  • -

#3 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 06 May 2013 - 06:52 AM

How would I go about checking the return values of the functions?

Is it something like:
if(fseek_return_value == 1)
{
	printf("Error");
}


What are the error values supposed to be?
Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 06:59 AM

You may want to start by finding and reading the documentation for these functions.

What does fseek() return when it fails? Hint: It's not necessarily 1, you should be checking to see whether or not it returns 0.

Jim
Was This Post Helpful? 0
  • +
  • -

#5 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 06 May 2013 - 07:05 AM

I tested this code and it proved that the file opened correctly
if(fp == NULL)
	{
		printf("Error");
	}



But for the time being would you be able to tell me why my if statement is always being satisfied?
Was This Post Helpful? 0
  • +
  • -

#6 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 07:17 AM

Probably because either your fseek() or fread() call failed.

Have you found and read the documentation for these functions?

What should you be using for the third argument for fseek()? Hint it's not a number.

Jim
Was This Post Helpful? 0
  • +
  • -

#7 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 06 May 2013 - 07:33 AM

Can't I use 0 instead of SEEK_SET? I was taught 0 = SEEK_SET, 1 = SEEK_CUR and 2 = SEEK_END.
Anyway for safe measure I tried SEEK_SET instead of 0 and I got the same results.

Also I read the documentation for fseek and found that the return value should be 0 so I tried
int fseek_ret_val;
	
	fseek_ret_val = fseek(fp, offset, SEEK_SET);
	
	if(fseek_ret_val == 0)
	{

		if((fread(&supp,sizeof(struct customer),1,fp)) != 1)
		{
			printf("\nError in reading file");
		}
		
		else
		{
			printf( "\nID: %d\nName: %s %s\nAge :%d\nGender: %c\nAddress: %s",
					supp.id, supp.first_name,supp.surname,supp.age,supp.gender, supp.address);
		}
	}
	
	else
	{
		printf("fseek() failed");
	}


And the if statement was satisfied, meaning that the fseek() is working correctly, hopefully.

I'll look up fread now
Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 07:45 AM

Quote

Can't I use 0 instead of SEEK_SET? I was taught 0 = SEEK_SET, 1 = SEEK_CUR and 2 = SEEK_END.

Not really no. You should not rely on the values to be 0, 1, and 2. Use the defined constants. The standard only states the following (from Section 7.21.1 of the last C11 draft standard):

Quote

SEEK_CUR
SEEK_END
SEEK_SET
which expand to integer constant expressions with distinct values, suitable for use as the
third argument to the fseek function;

As you should notice the standard doesn't actually state what values these Macros contain, just that they are constant integer expressions with distinct values, it is left to the compiler implementation as to what these values actually are.


Jim
Was This Post Helpful? 0
  • +
  • -

#9 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 06 May 2013 - 07:46 AM

The documentation says that fread returns a value equal to the number of elements read. I tried this
int freadval;
	
	freadval = (fread(&supp,sizeof(struct customer),1,fp));
	
	printf("\n%d\n",freadval);

And the output was 0. So that means that nothing is being read. Am I correct in saying that?
Was This Post Helpful? 0
  • +
  • -

#10 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 07:50 AM

Yes you're correct. Now you need to find out why. Try using perror() to try to determine why.

You still haven't posted a sample of your input file.

Jim
Was This Post Helpful? 0
  • +
  • -

#11 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 06 May 2013 - 08:58 AM

I attatched the customers.txt file, to this post, but here's a sample of the file anyway:

4567
Mike
Green
52
m
grafton street 5
4568
Svetlana
Reed
41
f
baker street 24
4569
Pat
Farrell
60
f

I tried using perror() with this code
if((fread(&supp,sizeof(struct customer),1,fp)) ==  NULL)
	{
		perror("The following error occurred");
	}
and this was my output:

The following error occurred: Success

Now I'm really confused. An fread value of 0 would indicate that it hasn't worked yet the perror output says success
Was This Post Helpful? 0
  • +
  • -

#12 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 09:18 AM

This doesn't look like a binary file to me.
4567
Mike
Green
52
m
grafton street 5
4568
Svetlana
Reed
41
f
baker street 24
4569
Pat
Farrell
60
f


Looks more like a plain text file. A binary file is not usually "human" readable. You don't normally use fread() and fseek() when using a text file.

Also you need to recheck your documentation for fread(), it doesn't return NULL. In C there is a difference between NULL and Zero.

Jim
Was This Post Helpful? 1
  • +
  • -

#13 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 06 May 2013 - 09:28 AM

I know I tried to attach the binary file in the original post but it wouldn't work. That .txt file has been converted to a binary file, "customers.bin"
Was This Post Helpful? 0
  • +
  • -

#14 jimblumberg  Icon User is online

  • member icon


Reputation: 4068
  • View blog
  • Posts: 12,550
  • Joined: 25-December 09

Re: fread() condition problem

Posted 06 May 2013 - 09:31 AM

As I said in order to attach your binary file you'll need to change the extension to .txt, not the contents of the file, just the extension. You'll also need to use the full editor.


Also you need to show what you inputted into your program for the offset value. Did you try reading the first record by commenting out the fseek() section of your code?

Also when you post the file please post your complete current code.

Jim

This post has been edited by jimblumberg: 06 May 2013 - 09:32 AM

Was This Post Helpful? 0
  • +
  • -

#15 Briscoooe  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 06-May 13

Re: fread() condition problem

Posted 07 May 2013 - 02:33 AM

I changed the extension on the customer.bin file to customer.txt and attatched it.

Here's the complete code so far

#include <stdio.h>
#include <stdlib.h>

//declare functions
void addsale(void);
void addcust(void);
void search(int answer, FILE *fp);
int getanswer(void);

//declare structures
struct customer
{
	int id;
	char first_name[11];
	char surname[21];
	int age;
	char gender;
	char address[50];
};

struct sales
{
	int id;
	char product_description[25];
	float price;
	int quantity;
};

int main()
{
	int selection;
	FILE *fp;
	int id_answer;
	
	fp = fopen("customers.bin","rb");
	
	start:
	
	printf("Enter one of the following numbers to select that option:\n\n1.) Add a new sale\n2.) Add a new customer\n"
			"3.) Search the file\n4.) Exit the program\n\n");
	
	//reading in users choice
	scanf("%d", &selection);
	
	switch(selection)
	{
			case 1:printf("\nYou selected option 1: Add a new sale\n");
					addsale();
					break;
			case 2:printf("\nYou selection option 2: Add a new customer\n");
					addcust();
					break;
			case 3:printf("\nYou selected option 3: Search the file\n");
					id_answer = getanswer();
					search(id_answer, fp);
					break;
			case 4: return 0;
			default:printf("\nERROR: Invalid character entered\n\n");
					goto start;
					break;
     }
	
	return 0;
}

void addsale(void)
{
	struct sales new_sale;
	
	FILE *fpsales;
	FILE *fpsalesbin;
	
	fpsales = fopen("sales.txt","r");
	fpsalesbin = fopen("sales.bin","w+b");
	
	if (fpsales == NULL)
	{
		printf("\nERROR: File not found\n");
		exit(1);
	}
	
	else
	{
		printf("\nEnter sale ID: ");
		scanf("%d",&new_sale.id);
		
		printf("Enter sale price: ");
		scanf("%f",&new_sale.price);
		
		printf("Enter sale quantity: ");
		scanf("%d",&new_sale.quantity);
		
		printf("Enter sale description: ");
		scanf("%s*c",&new_sale.product_description);
	}
	
	fscanf(fpsalesbin, "%d %f %d %s\n", new_sale.id,
										new_sale.price,
										new_sale.quantity,
										new_sale.product_description
										);
										
	fclose(fpsales);
	fclose(fpsalesbin);
}

void addcust(void)
{
	struct customer new_cust;
	
	FILE *fpcust;
	FILE *fpcustbin;
	
	fpcust = fopen("customers.txt","a");
	fpcustbin = fopen("customers.bin","w+b");
	
	if (fpcust == NULL)
	{
		printf("\nERROR: File not found\n");
		exit(1);
	}
	
	else
	{
		printf("\nEnter customer ID: ");
		scanf("%d",&new_cust.id);
		
		//insert error checking to make sure customer ID doesn't already exist
		
		printf("Enter customer firstname: ");
		scanf("%s*c",&new_cust.first_name);
		
		printf("Enter customer surname: ");
		scanf("%s*c", &new_cust.surname);
		
		printf("Enter customer age: ");
		scanf("%d",&new_cust.age);
		
		printf("Enter customer gender(M or F): ");
		scanf("%c",&new_cust.gender);
		
		printf("Enter customer address: ");
		scanf("%s*c",&new_cust.address);
	
	}
	
	fscanf(fpcustbin, "%d %s %s %d %c %s\n", 	new_cust.id,
										new_cust.first_name,
										new_cust.surname,
										new_cust.age,
										new_cust.gender,
										new_cust.address
										);
										
	fclose(fpcust);
	fclose(fpcustbin);
}

void search(int answer,FILE *fp)
{
	struct customer
	{
		int id;
		char first_name[11];
		char surname[21];
		int age;
		char gender;
		char address[50];
	};
	
	struct customer supp;
	int offset;

	offset = (answer - 1) * sizeof(struct customer);
	fseek(fp, offset, 0);

	if((fread(&supp,sizeof(struct customer),1,fp)) != 1)
	{
		printf("\nError in reading file");
	}
	
	if((fread(&supp,sizeof(struct customer),1,fp)) ==  NULL)
	{
		perror("The following error occurred");
	}
	
	else
	{
		printf( "\nID: %d\nName: %s %s\nAge :%d\nGender: %c\nAddress: %s",
				supp.id, supp.first_name,supp.surname,supp.age,supp.gender, supp.address);
	}
}

int getanswer(void)
{
	int answer;
	
	printf("\nEnter a user ID to display their information: ");
	scanf("%d",&answer);

	return(answer);
}



Quote

Did you try reading the first record by commenting out the fseek() section of your code?


What do you mean by this?
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3