• 0

[C] Another C problem..


Question

So this program receives some inputs from the user like name,age and city and write these to a file. It is intended to do so till the user inputs Y OR y, but after receiveing the first set of inputs it just ends..

Can anyone please sort it out ?

#include<stdio.h>
const char FILE_NAME[]="employee.dat";
struct emp
{
	char name[40];
	int age;	
	char city[30];
};
struct emp e;
int main()
{
	FILE *fp;
	char another;
	fp=fopen(FILE_NAME,"w");
	while(1)
	{
		printf("Enter name age and city of the employee\n");
		scanf("%s%d%s",e.name,&e.age,e.city);
		fprintf(fp,"%s\t%d\t%s\n\n",e.name,e.age,e.city);
		printf("Do you want to enter another record\n");
		fflush(stdin);
		scanf("%c",&another);
		if(another!='Y' || another!='y')
			break;
	}
	return(0);
}

Link to comment
Share on other sites

14 answers to this question

Recommended Posts

  • 0

if(another!='Y' || another!='y')

should be

if(another!='Y' && another!='y')

otherwise the condition will always be true.

EDIT: looks like Jonathan beat me to it.

Link to comment
Share on other sites

  • 0

Put a space before the %c in the scanf.

It's something about the newline from the previous scanf being caught the next time it's called.

#include<stdio.h>
const char FILE_NAME[]="employee.dat";
struct emp
{
	char name[40];
	int age;	
	char city[30];
};
struct emp e;
int main()
{
	FILE *fp;
	char another;
	fp=fopen(FILE_NAME,"w");
	while(1)
	{
		printf("Enter name age and city of the employee\n");
		scanf("%s%d%s",e.name,&e.age,e.city);
		fprintf(fp,"%s\t%d\t%s\n\n",e.name,e.age,e.city);
		printf("Do you want to enter another record\n");
		fflush(stdin);
		scanf(" %c",&another);
		if(another!='Y' && another!='y')
			break;
	}
	return(0);
}

Link to comment
Share on other sites

  • 0

Here's a quick recode, I'm kind of in the middle of something so I didn't check for errors or try compiling it:

#include <stdio.h>
#include <tchar.h>

static const char szFileName[] = _T("employee.dat");

typedef struct _EMPLOYEE_DATA {
  char  szName[40];
  char  szCity[30];
  int   iAge;
} EMPLOYEE_DATA, EMPLOYEE;

int __cdecl main(void)
{
  EMPLOYEE  employee;
  FILE*	 fp;


  fp = _tfopen(szFileName, _T("a"));
  if (fp != NULL)
  {
	do
	{
	  _tprintf(_T("Enter the name, age & city of the employee: "));
	  if (_tscanf(_T("%s %d %s"), employee.szName, &employee.iAge, employee.szCity) == 3)
	  {
		_ftprintf(fp, _T("%s\t%d\t%s\r\n\r\n"), employee.szName, employee.iAge, employee.szCity);
		_tprintf(_T("Would you like to enter another record? "));
	  }
	  else
	  {
		_ftprintf(stderr, _T("Invalid input, please enter the correctly formatted data!\r\n"));
		continue;
	  }
	} while (_totupper(_gettchar()) == _T('Y'));
	// clean up & exit
	fclose(fp);
	return EXIT_SUCCESS;
  }
  else
  {
	_ftprintf(stderr, _T("Could not open/create the employee records file, aborting!"));
	return EXIT_FAILURE;
  }
}

Good luck.

Edited by x0r
Link to comment
Share on other sites

  • 0

^^ i want to know whats wrong with the code i wrote..

so now i did some modifications.. a guy told me to use fgets and sscanf instead of fprintf..

#include<stdio.h>
const char FILE_NAME[]="emp.dat";
struct emp
{
	char name[30];
	int age;
	char city[30];
};
struct emp e;
int main()
{
	char ch;
	char line[100];
	FILE *fp;
	fp=fopen(FILE_NAME,"wb");
	while(1)
	{
		printf("Enter name,age and city\n");
		fgets(line,sizeof(line),stdin);		
		sscanf(line,"%s%d%s",e.name,&e.age,e.city);		
		fwrite(&e,sizeof(e),1,fp);
		printf("Enter another record\n");
		fflush(stdin);
		scanf("%c",&ch);
		if(ch!='Y')
			break;

	}
	return(0);
}

so the output of this is

58331981.th.jpg

Link to comment
Share on other sites

  • 0

Here's the corrected code for ya:

#include<stdio.h>
const char FILE_NAME[]="employee.dat";
struct emp
{
	char name[40];
	int age;	
	char city[30];
};
struct emp e;
int main()
{
	FILE *fp;
	char another;
	fp=fopen(FILE_NAME,"w");
	while(1)
	{
		repeat: printf("Enter name age and city of the employee\n");
		scanf("%s%d%s",e.name,&e.age,e.city);
		fprintf(fp,"%s\t%d\t%s\n\n",e.name,e.age,e.city);
		printf("Do you want to enter another record\n");
		fflush(stdin);
		scanf("%c",&another);
		if(another!='Y' || another!='y')
			goto repeat;
	}
	return(0);
}

Your problem simply lied in the If block.Your code will break the flow of program if the answer is 'y' or 'Y'! That doesn't make sense.I changed that with a goto statement so it will repeat itself.But you'll also have to define alternate conditions where user may input a wrong character which causes the program to bring about an exception or the user may reply with 'n' so the program can quit correctly.I glanced through the code x0r wrote and it seemed right and a lot more elaborated.

@kli6891 & Jonathan Amend: You two got it wrong there.The code of OP was correct in that part.

Link to comment
Share on other sites

  • 0
but i was told that one should avoid using goto statements as it is not a characteristic of good programming..?
You are right. In this case, it is trivial to move the condition to the while statement and avoid the goto.

char another = 'y';
while (another=='y' || another=='Y') {
	// do your thing
	// prompt for new record ('y'/'n')
	// store input in another
}

fflush(stdin) might work or not. Its behavior is undefined, it's supported by certain compilers and not by others. What happens when you use scanf is that it leaves the new line character in the input buffer, so when the next scanf is called, it finds that character in the buffer and immediately returns instead of waiting for using input as it should. Using fflush(stdin) after scanf is supposed to, as the name implies, flush the standard input, but there's no guarantee that doing this works on your particular system.

The proper way of handling user input in C is to loop around getchar() and process each character individually, including newline characters. Do your little research on Google for examples. (for instance this.)

The even better way is to compile as C++ and use the C++ standard library because unlike the C library, it actually works. :p Unfortunately that's not always an option.

Edited by Dr_Asik
Link to comment
Share on other sites

  • 0
@kli6891 & Jonathan Amend: You two got it wrong there.The code of OP was correct in that part.

no, they were correct.

Here's boolean algebra 101

if(another!='Y' || another!='y')

Allow + to be OR, & to be AND, ! to be NOT

the if statement is equivalent to:

!Y + !y

using demorgans theorem, it turns to

!(Y&y)

now look at this, if ANOTHER is 'Y' can it be 'y' at the same time? (this isn't quantum computing :D)

so if it is 'Y' and it isn't little 'y' using logical numbers its:

!(1&0)=!(0)=1 (true)

So if its 'Y', 'y', or anything else it will always be true. And it will always break!

Link to comment
Share on other sites

  • 0

i compile the programs using GCC..

and when i specify conio.h for getch() or getche(), it says it is unable to find that file..

so is there any alternative to conio.h??

Link to comment
Share on other sites

  • 0

so.. problem solved..

here's what i did as was told on another forum by sizeablegrin :D..

i used fgets to get all the values in the string and later on parsed them using sscanf..

i did same thing with another variable...

and problem solved..

#include<stdio.h>
const char FILE_NAME[]="employee.dat";
struct emp
{
	char name[40];
	int age;	
	char city[30];
};
struct emp e;
int main()
{
	FILE *fp;
	char another;
	char line[100];
	fp=fopen(FILE_NAME,"w");
	while(1)
	{
		printf("Enter name age and city of the employee\n");
		fgets(line,sizeof(line),stdin);
		sscanf(line,"%s%d%s",e.name,&e.age,e.city);
		fprintf(fp,"%s\t%d\t%s\n\n",e.name,e.age,e.city);
		printf("Do you want to enter another record\n");
		fgets(line,sizeof(line),stdin);		
		sscanf(line,"%c",&another);
		if(another!='Y' && another!='y')
			break;
	}
	return(0);
}

Link to comment
Share on other sites

  • 0
no, they were correct.

Here's boolean algebra 101

if(another!='Y' || another!='y')

Allow + to be OR, & to be AND, ! to be NOT

the if statement is equivalent to:

!Y + !y

using demorgans theorem, it turns to

!(Y&y)

now look at this, if ANOTHER is 'Y' can it be 'y' at the same time? (this isn't quantum computing :D)

so if it is 'Y' and it isn't little 'y' using logical numbers its:

!(1&0)=!(0)=1 (true)

So if its 'Y', 'y', or anything else it will always be true. And it will always break!

What are you on about?

It doesn't need all that gibberish you posted to understand what the OP posted was correct in that regard.Dr_Asik also confirmed this with his code.

It's simple: && ==AND but ||==OR('y' or 'Y'), the latter should be used here.

@OP- Good for you!

And yeah, the goto statement isn't the best way of repeating things.I've been told about that too.But that was just off the top of my head, I'm kinda used to that statement, guess I should throw it off my head. :)

EDIT-@ekw- Scratch the above. :blush: I'm sorry I didn't notice that the operator he used for comparsion was '!='. I don't know why, but I saw that as '='.Hence the errors I made in this and the previous post.

Edited by Aquarian
Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.