Thread: File Question

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    15

    File Question

    Code:
    #include<stdio.h>
    #include<conio.h>
    #include<stdlib.h>
    struct customer
    {
    	int accno;
    	char name[30];
    	float balance;
    }cust;
    struct trans
    {
    	int accno;
    	char trans_type;
    	float amount;
    }tran;
    int size;
    void create();
    void list();
    void status();
    void main()
    {
    	int op;
    	size=sizeof(cust);
    	while(1)
    	{
    		printf("1.Create\n2.List\n3.Status\n5.Exit\n");
    		scanf("%d",&op);
    		switch(op)
    		{
    			case 1: create();
    				break;
    			case 2: list();
    				break;
    			case 3: status();
    				break;
    			case 5: exit(1);
    			default: clrscr();break;
    		}
    	}
    	getch();
    }
    void status()
    {
    	FILE *fp,*ft;
    	int iden;
    	clrscr();
    	printf("ACCOUNT NUMBER\t\tTRANSACTION\t\tSTATUS\t\tUPDATE\n");
    	fp=fopen("Customer.dat","rb+");
    	if(fp==NULL)
    	{
    		puts("CANNOT OPEN CUSTOMER FILE!!\n");
    		return;
    	}
    	ft=fopen("Transactions.dat","rb+");
    	if(ft==NULL)
    	{
    		puts("CANNOT OPEN TRANSACTION FILE!!\n");
    		return;
    	}
    	while(1)
    	{
    		iden=fread(&cust,size,1,fp);
    		fread(&tran,sizeof(tran),1,ft);
    		if(iden==0)
    			break;
    		else
    		{
    			//printf("%d\t%s\t%f\n",cust.accno,cust.name,cust.balance);
    			if(tran.trans_type=='D')
    			{
    				cust.balance=cust.balance+tran.amount;
    				fseek(fp,-size,SEEK_CUR);
    				fwrite(&cust,size,1,fp);
    				printf("%d\t\tDEPOSIT\t\tSUCCESSFUL\t\t%f\n",cust.accno,cust.balance);
    			}
    			else
    			{
    				if(cust.balance-tran.amount<100)
    					printf("%d\t\tWITHDRAWAL\t\tFAILED\t\t%f\n",cust.accno,cust.balance);
    				else
    				{
    					cust.balance=cust.balance-tran.amount;
    					fseek(fp,-size,SEEK_CUR);
    					fwrite(&cust,size,1,fp);
    					printf("%d\t\tWITHDRAWAL\t\tFAILED\t\t%f\n",cust.accno,cust.balance);
    				}
    			}
    		}
    	}
    	fclose(fp);fclose(ft);
    }
    void list()
    {
    	FILE *fp,*ft;
    	int iden=0;
    	fp=fopen("Customer.dat","rb");
    	if(fp==NULL)
    	{
    		puts("CANNOT OPEN CUSTOMER FILE!!\n");
    		exit(1);
    	}
    	ft=fopen("Transactions.dat","rb");
    	if(ft==NULL)
    	{
    		puts("CANNOT OPEN TRANSACTION FILE!!\n");
    		exit(2);
    	}
    	while(1)
    	{
    		iden=fread(&cust,sizeof(cust),1,fp);
    		fread(&tran,sizeof(tran),1,ft);
    		if(iden==0)
    			break;
    		printf("%s\t%d\t%f\n",cust.name,cust.accno,cust.balance);
    		printf("%d\t%c\t%f\n\n",tran.accno,tran.trans_type,tran.amount);
    	}
    	fclose(ft);fclose(fp);
    }
    void create()
    {
    	FILE *fp,*ft;
    	int iden;
    	char another;
    	fp=fopen("Customer.dat","rb+");
    	if(fp==NULL)
    	{
    		fp=fopen("Customer.dat","wb");
    		if(fp==NULL)
    		{
    			puts("CANNOT OPEN CUSTOMER FILE!!\n");
    			exit(1);
    		}
    	}
    	ft=fopen("Transactions.dat","rb+");
    	if(ft==NULL)
    	{
    		ft=fopen("Transactions.dat","wb");
    		if(ft==NULL)
    		{
    			puts("CANNOT OPEN TRANSACTION FILE!!\n");
    			exit(2);
    		}
    	}
    	fseek(fp,0,SEEK_END);
    	fseek(ft,0,SEEK_END);
    	another='Y';
    	while(another=='Y')
    	{
    		printf("ENTER Name, ACCOUNT NUMBER AND BALANCE\n");
    		fflush(stdin);
    		gets(cust.name);
    		scanf("%d%f",&cust.accno,&cust.balance);
    		printf("TRANSACTIONS TYPE [D FOR DEPOSIT,W FOR WITHDRAWAL] ,ENTER ACCOUNT NUMBER,AND AMOUNT\n");
    		fflush(stdin);
    		scanf("%c%d%f",&tran.trans_type,&tran.accno,&tran.amount);
    		fwrite(&cust,sizeof(cust),1,fp);
    		fwrite(&tran,sizeof(tran),1,ft);
    		fflush(stdin);
    		printf("DO YOU WANT TO ADD ANOTHER RECORD [Y/N]\n");
    		scanf("%c",&another);
    	}
    	clrscr();
    	rewind(fp);rewind(ft);
    	fclose(fp);fclose(ft);
    }
    I wrote this file program which takes two file one customer.dat and the other- transactions.dat and it's suppose to take the amount in transaction file and deposit or withdraw from customer balance according to ther user input. D for deposit W for withdraw.

    For some reason it's only working for the first customer account and skips the rest. Any Suggestions would be appreciated!

    Thank You!

  2. #2
    ---
    Join Date
    May 2004
    Posts
    1,379
    I'm not 100&#37; sure but maybe scanf() is holding the '\n' in the input buffer. So the next iteration it is going straight to the default case.
    Try flushing the input buffer after calling scanf()

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    %d can deal with \n in the input buffer, but %c (in your create routine, which I assume is the one you typically call first) cannot.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    Well I see you've used "void main", "fflush(stdin)" and "gets(buff)".
    All of these are wrong in the worst possible way.
    There are FAQ entries on each one of them.

    Throw away whatever books you're reading, leave whatever class you're attending. Because you're just learning a pile of rubbish.

    But these have all been mentioned (several times already in your other posts), so I have to conclude that you're simply not listening and are quite happy just so long as you see your expected results.

    In which case, don't forget to
    #include <randomly_bite_my_ass.h>
    in your code, just for when you do decide to upgrade your ancient technology and find out that all the stuff you've learnt so far is total crap.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    15
    Code:
    #include<stdio.h>
    #include<conio.h>
    #include<stdlib.h>
    struct customer
    {
    	int accno;
    	char name[30];
    	float balance;
    }cust;
    struct trans
    {
    	int accno;
    	char trans_type;
    	float amount;
    }tran;
    int size;
    int create();
    int list();
    int status();
    int main()
    {
    	int op;
    	size=sizeof(cust);
    	while(1)
    	{
    		printf("1.Create\n2.List\n3.Status\n5.Exit\n");
    		scanf("%d",&op);
    		switch(op)
    		{
    			case 1: create();
    				break;
    			case 2: list();
    				break;
    			case 3: status();
    				break;
    			case 5: exit(1);
    			default: clrscr();break;
    		}
    	}
    	getchar();
    	return 0;
    }
    int status()
    {
    	FILE *fp,*ft;
    	int iden;
    	clrscr();
    	printf("ACCOUNT NUMBER\t\tTRANSACTION\t\tSTATUS\t\tUPDATE\n");
    	fp=fopen("Customer.dat","rb+");
    	if(fp==NULL)
    	{
    		puts("CANNOT OPEN CUSTOMER FILE!!\n");
    		return;
    	}
    	ft=fopen("Transactions.dat","rb+");
    	if(ft==NULL)
    	{
    		puts("CANNOT OPEN TRANSACTION FILE!!\n");
    		return;
    	}
    	while(1)
    	{
    		iden=fread(&cust,size,1,fp);
    		fread(&tran,sizeof(tran),1,ft);
    		if(iden==0)
    			break;
    		else
    		{
    			//printf("%d\t%s\t%f\n",cust.accno,cust.name,cust.balance);
    			if(tran.trans_type=='D')
    			{
    				cust.balance=cust.balance+tran.amount;
    				fseek(fp,-size,SEEK_CUR);
    				fwrite(&cust,size,1,fp);
    				printf("%d\t\tDEPOSIT\t\tSUCCESSFUL\t\t%f\n",cust.accno,cust.balance);
    			}
    			else
    			{
    				if(cust.balance-tran.amount<100)
    					printf("%d\t\tWITHDRAWAL\t\tFAILED\t\t%f\n",cust.accno,cust.balance);
    				else
    				{
    					cust.balance=cust.balance-tran.amount;
    					fseek(fp,-size,SEEK_CUR);
    					fwrite(&cust,size,1,fp);
    					printf("%d\t\tWITHDRAWAL\t\tFAILED\t\t%f\n",cust.accno,cust.balance);
    				}
    			}
    		}
    	}
    	fclose(fp);fclose(ft);
    	return 0;
    }
    int list()
    {
    	FILE *fp,*ft;
    	int iden=0;
    	fp=fopen("Customer.dat","rb");
    	if(fp==NULL)
    	{
    		puts("CANNOT OPEN CUSTOMER FILE!!\n");
    		exit(1);
    	}
    	ft=fopen("Transactions.dat","rb");
    	if(ft==NULL)
    	{
    		puts("CANNOT OPEN TRANSACTION FILE!!\n");
    		exit(2);
    	}
    	while(1)
    	{
    		iden=fread(&cust,sizeof(cust),1,fp);
    		fread(&tran,sizeof(tran),1,ft);
    		if(iden==0)
    			break;
    		printf("%s\t%d\t%f\n",cust.name,cust.accno,cust.balance);
    		printf("%d\t%c\t%f\n\n",tran.accno,tran.trans_type,tran.amount);
    	}
    	fclose(ft);fclose(fp);
    	return 0;
    }
    int create()
    {
    	FILE *fp,*ft;
    	int iden;
    	char another;
    	fp=fopen("Customer.dat","rb+");
    	if(fp==NULL)
    	{
    		fp=fopen("Customer.dat","wb");
    		if(fp==NULL)
    		{
    			puts("CANNOT OPEN CUSTOMER FILE!!\n");
    			exit(1);
    		}
    	}
    	ft=fopen("Transactions.dat","rb+");
    	if(ft==NULL)
    	{
    		ft=fopen("Transactions.dat","wb");
    		if(ft==NULL)
    		{
    			puts("CANNOT OPEN TRANSACTION FILE!!\n");
    			exit(2);
    		}
    	}
    	fseek(fp,0,SEEK_END);
    	fseek(ft,0,SEEK_END);
    	another='Y';
    	while(another=='Y')
    	{
    		printf("ENTER Name, ACCOUNT NUMBER AND BALANCE\n");
    		scanf("%s%d%f",&cust.name,&cust.accno,&cust.balance);
    		printf("TRANSACTIONS TYPE [D FOR DEPOSIT,W FOR WITHDRAWAL] ,ENTER ACCOUNT NUMBER,AND AMOUNT\n");
    		scanf("%s%d%f",&tran.trans_type,&tran.accno,&tran.amount);
    		fwrite(&cust,sizeof(cust),1,fp);
    		fwrite(&tran,sizeof(tran),1,ft);
    		fflush(stdin);
    		printf("DO YOU WANT TO ADD ANOTHER RECORD [Y/N]\n");
    		scanf("%c",&another);
    	}
    	clrscr();
    	fclose(fp);fclose(ft);
    	return 0;
    }
    Thank you guys, but my problem is in the status function it only prints the first account and skips the rest, sorry i didn't mention that earlier..! I just can't figure out what i did wrong with this stupid program!

    I have also corrected most of the fflush(stdin) and void, very very very very kindly mentioned by salem.

    I don't think it's ancient technology, i'm using borland c++ 4.5 and when i use c++ functions
    system("cls") and system("pause"); i get an error, so i had to go the other way.

    Salem : so Dennis Ritchie must be stupid enough to include all these useless (gets, fflush,voidd main) functions eh??

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by kolliash View Post
    I don't think it's ancient technology, i'm using borland c++ 4.5 and when i use c++ functions
    Which came out 94 or so. Ancient? I'd say so.

    Salem : so Dennis Ritchie must be stupid enough to include all these useless (gets, fflush,voidd main) functions eh??
    Yes.
    The fact that Dennis relies on undefined behavior is idiotic and the fact that Dennis uses the never-should-have-been-invented-incredibly-unsecure gets is proof that Dennis is either uneducated or a moron.
    Gets has no place in C due to its unsafe nature. If you're going to use C, then you will have to take responsibility of make your code safe, because C isn't safe by nature. But that's the price you have to pay for dealing with such low level.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Note that only gets() is used in a valid way according to the C89 Standard (which in turn is based on Dennis Ritchie's work).
    fflush(stdin) is undefined according to the standard, void main() likewise. Many compilers will actually complain about void main() - they may not recognize fflush(stdin) as bad - but I'm sure sufficient trying, you'll sooner or later find an environment where fflush() of a file opened for read only leads to unexpected results, such as incorrect IO or a crash.

    Note that gets() is only insecure in an environment where privilege hoisting can be achieved - so if you are running as an ordinary user, in a relatively safe OS, it is likely that it will only cause your application to crash, nothing worse. It is still a pretty bad thing if someone has been working for 2 hours inputting data, happens to hit a few too many keys and crashes out of the application.

    Of course, used in an environment where someone could also hoist their privileges by inputting the right (wrong?) overly long input is a worse scenario, because now the entire machine is vulnerable.

    Both of these can EASILY be fixed, and there are safe input methods in C - such as fgets().

    Edit: To clarify, I'm pretty sure that Dennis Ritchie does not officially recommend void main() to be used. I'm SURE that he doesn't recommend fflush(stdin), and also do not recommend using gets() for input of user data other than in simple examples.

    --
    Mats
    Last edited by matsp; 06-10-2008 at 06:43 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You forget that it's a security risk, as well.
    http://cpwiki.sourceforge.net/Gets
    Gets makes the computer prone to executing malicious code, and you wouldn't want that, now would you?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    You forget that it's a security risk, as well.
    http://cpwiki.sourceforge.net/Gets
    Gets makes the computer prone to executing malicious code, and you wouldn't want that, now would you?
    Yes, sure, but I see privilege hoisting as a bigger concern.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    gets() is one of those ancient historic functions from way way back in time, when C itself was still little more than a lab experiment, and everyone could be trusted to do the right thing.

    There's plenty of other C anomalies as well, which with the benefit of 40 years of hindsight don't look so clever either. But that's history for you.
    gets() is there for backward compatibility only. gcc in particular warns you if you try to link with it, and the next C standard is likely to deprecate it (it's a dying function). I'm somewhat dismayed that ISO didn't decide to deprecate it in C99, but there you go.

    And no, void main and fflush(stdin) are DOS-based compiler writers bone-headed decisions, and nothing to do with proper C.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A development process
    By Noir in forum C Programming
    Replies: 37
    Last Post: 07-10-2011, 10:39 PM
  2. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  3. Post...
    By maxorator in forum C++ Programming
    Replies: 12
    Last Post: 10-11-2005, 08:39 AM
  4. Encryption program
    By zeiffelz in forum C Programming
    Replies: 1
    Last Post: 06-15-2005, 03:39 AM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM