C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 08-02-2009, 01:31 PM   #1
Registered User
 
Join Date: Aug 2009
Posts: 11
Post Turbo C Structures and Writing to file help

Hey everyone, I'm basically very new at this and I need to finish a program to finish my C programming course. My main problem is when writing to a file the information of a structure. It works fine, it writes to the file but it terminates the program as soon as the function ends, and it's not supposed to do that. I've been trying to debug for 2 hours now, and still nothing... Can anyone show me some examples of 'fread' and 'fwrite' in use? I don't want to paste my entire current program because it's quite long, but here's the function that I'm having trouble with:

Code:
void f_add_student(void)
{
 int lv_id;
 student_rec s_students;
 char lv_continue;
 int lv_cancel;
 clrscr();
 if((file_student_rec=fopen(c_student_rec,"rb+"))==NULL)
  {
   f_dialog_border();
   gotoxy(13,24);
   printf("First student addition, a file will be created to store your");
   gotoxy(37,27);
   printf("information.");
   getch();
   s_students.id=1;
   clrscr();
   file_student_rec=fopen(c_student_rec,"a+");
  }
 else
  {
   do{
    lv_id=s_students.id;
    fread(&s_students,sizeof(s_students),1,file_student_rec);
   }while(!feof(file_student_rec));
   s_students.id=lv_id+1;
  }
 f_clear_variable(s_students.fname);
 f_clear_variable(s_students.lname);
 f_clear_variable(s_students.address);
 f_clear_variable(s_students.phone);
 s_students.age=0;
 s_students.gender=0x00;
 do{
  clrscr();
  gotoxy(36,14);
  printf("Add Student");
  gotoxy(15,17);
  printf("ID: %05i",s_students.id);
  gotoxy(15,19);
  printf("First Name:");
  gotoxy(15,21);
  printf("Last Name:");
  gotoxy(15,23);
  printf("Address:");
  gotoxy(15,25);
  printf("Age:");
  gotoxy(15,27);
  printf("Gender:");
  gotoxy(15,29);
  printf("Phone Number:");
  f_main_border();
  fflush(stdin);
  gotoxy(28,19);
  gets(s_students.fname);
  gotoxy(27,21);
  gets(s_students.lname);
  gotoxy(24,23);
  gets(s_students.address);
  gotoxy(20,25);
  scanf("%i",&s_students.age);
  fflush(stdin);
  gotoxy(23,27);
  scanf("%c",&s_students.gender);
  fflush(stdin);
  gotoxy(30,29);
  gets(s_students.phone);
  f_dialog_border();
  printf("Are you sure you want to add this student to student records[y/n]?");
  scanf("%c",&lv_continue);
  fflush(stdin);
  if(lv_continue=='n' || lv_continue=='N')
   lv_cancel=1;
  else
   lv_cancel=0;
 }while(lv_cancel==1);
 s_students.s_grades.History=0;
 s_students.s_grades.Geography=0;
 s_students.s_grades.Math=0;
 s_students.s_grades.English=0;
 s_students.s_grades.Humanities=0;
 s_students.s_grades.Science=0;
 s_students.s_grades.Art=0;
 s_students.s_grades.PE=0;
 fwrite(&s_students,sizeof(s_students),1,file_student_rec);
 fclose(file_student_rec);
}

Last edited by PHGDAL; 08-02-2009 at 01:42 PM. Reason: Forgot the code tags...
PHGDAL is offline   Reply With Quote
Old 08-02-2009, 02:04 PM   #2
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
fflush(stdin) will result in undefined behavior:

Quote:
Originally Posted by C Draft Standard 2005
If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.
This is a common misuse of fflush(). Get rid of it.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is offline   Reply With Quote
Old 08-02-2009, 02:07 PM   #3
Registered User
 
Join Date: Aug 2009
Posts: 11
How do I clear the input stream without fflush(stdin)?
PHGDAL is offline   Reply With Quote
Old 08-02-2009, 02:30 PM   #4
Registered User
 
GL.Sam's Avatar
 
Join Date: Aug 2009
Posts: 39
Omg, it looks horrible. First off, you definetely should get rid of unneeded gotoxy() instances. It is non-standard C, there are plenty possibilities of using escape sequences instead, but the main reason is darn uglyness.

>How do I clear the input stream without fflush(stdin)?

The general example goes like this:
Code:
while (getchar() != '\n')
  continue;
Also,
Code:
fread(&s_students,sizeof(s_students),1,file_student_rec);
fwrite(&s_students,sizeof(s_students),1,file_student_rec);
should be
Code:
fread(&s_students,sizeof(student_rec),1,file_student_rec);
fwrite(&s_students,sizeof(student_rec),1,file_student_rec);

Last edited by GL.Sam; 08-02-2009 at 02:42 PM.
GL.Sam is offline   Reply With Quote
Old 08-02-2009, 02:34 PM   #5
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
Quote:
Originally Posted by PHGDAL View Post
How do I clear the input stream without fflush(stdin)?
This is actually the 2nd time this has come up today. You may want to read this thread from yesturday for more info:

fgetchar() doesnt work
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is offline   Reply With Quote
Old 08-02-2009, 06:17 PM   #6
Super Moderator
 
Bubba's Avatar
 
Join Date: Aug 2001
Posts: 7,470
First piece of advice I have is get MSVS Express 2008 and dump Turbo C. MSVS can compile C or C++ or both and.
__________________
If you aim at everything you will hit something but you won't know what it is.
Bubba is offline   Reply With Quote
Old 08-02-2009, 10:21 PM   #7
Registered User
 
Join Date: Aug 2009
Posts: 11
Thanks everyone, I'll give it a try. Unfortunately I can't use any other program, my course demands that I use turbo C for this project otherwise I don't pass. For the gotoxy() bits it's to get the writing inside the borders I drew with a different function. I don't know any other way to do it...
PHGDAL is offline   Reply With Quote
Old 08-02-2009, 11:14 PM   #8
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
Ask your tutor why they insist on using a compiler which is older than the students, and is obsolete both as a compiler and the OS it was intended to run on.

Who is paying for your course, and will your qualification be worth anything in the real world where NOBODY else uses that fossil?
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-02-2009, 11:38 PM   #9
Registered User
 
Join Date: Aug 2009
Posts: 11
I thought the same thing too. But it's really only a simple 24-hour long course (3 hours a day, 2 days a week) just so I can get the basics of the language. I'll probably take a more useful course on C++ or C# later.
PHGDAL is offline   Reply With Quote
Old 08-02-2009, 11:39 PM   #10
DESTINY
 
BEN10's Avatar
 
Join Date: Jul 2008
Location: in front of my computer
Posts: 656
Quote:
Originally Posted by Salem View Post
Ask your tutor why they insist on using a compiler which is older than the students, and is obsolete both as a compiler and the OS it was intended to run on.

Who is paying for your course, and will your qualification be worth anything in the real world where NOBODY else uses that fossil?
There are a lot of universities who still teach C using TC, and you can't say anything to them like "Why are you using this fossil" coz it's going on for long and nobody cares what you say? So, IMO, the OP should run the code on TC and on any modern compiler for the sake of his/her understanding.
__________________
HOPE YOU UNDERSTAND.......

for( ; ; )
printf("If you can't make it good, at least make it look good");

PC specifications- 512MB RAM, Windows XP sp3, 2.79 GHz pentium D.
IDE- Microsoft Visual Studio 2008 Express Edition
BEN10 is offline   Reply With Quote
Old 08-03-2009, 12:00 AM   #11
Registered User
 
Join Date: Aug 2009
Posts: 11
Ok, I changed all the fflush(stdin)'s to getchar()!='\n' and I also changed

Code:
fread(&s_students,sizeof(s_students),1,file_student_rec);
fwrite(&s_students,sizeof(s_students),1,file_student_rec);
to
Code:
fread(&s_students,sizeof(student_rec),1,file_student_rec);
fwrite(&s_students,sizeof(student_rec),1,file_student_rec);
but the problem is still there, the program exits after ending the function instead of returning to the last function. I attached the *.cpp file of the whole program just in case it helps. Thanks everyone in advance!
Attached Files
File Type: cpp OS_TESTI.CPP (16.0 KB, 33 views)
PHGDAL is offline   Reply With Quote
Old 08-03-2009, 01:57 AM   #12
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
Okay, I don't have windows installed so I cannot test this code, but I looked at it for a while and here's a preliminary observation: You use a flag, "lv_choice", quite a few times, in void() functions with a switch in a while loop to "end" the function:
Code:
  }while(lv_choice==0);   //End of while loop.
}
You can return from a void function. In other words, rather than doing all that with the lv_choice flag, in the cases where you set the flag:
Code:
    case 5:              //Logout.
    {
    f_logout();
    lv_choice=1;
    break;
    }
You should just replace "break" with "return", change the loop to an infinite one:
Code:
while (1) {
       [...code...]
}
and remove all references to lv_choice. This will
  1. simplify the code
  2. reduce the usage of memory by eliminating a superfluous variable
  3. improve efficiency by removing a number of superfluous operations
Those last two are sort of minor, on this scale, but they are indicative of how you should be thinking about programming; the first one is significant here IMO, because it amounts to a lot of clutter. In any case, these two perogatives (simplifying where ever possible, and streamlining the actual functionality of the process) go hand in hand.

Also, using a tabstop of at least two characters would be nice.

As for your problem, here is a strong possibility (again, I can't test this because of conio.h): it has to do with flushing the input buffer again. Did you read the thread I pointed you to to do with how '\n' gets left in the input buffer by scanf if you use %d %i or %c?

Let's look at the flow of execution with that in mind. You believe f_add_student() is to blame. f_add_student gets called here, in f_student_options():
Code:
  scanf("%i",&lv_choice);
  switch(lv_choice)
   {
    case 1:                        //Add Student.
     f_add_student();
     lv_choice=0;
     break;
Notice, before you even begin, there is an '\n' left in the buffer. This will not get picked up by a %d or %i but it will get into a %c. That will get taken care of by your "while(getchar()!='\n')", altho these all have a strange form:
Code:
  while(getchar()!='\n')
      s_students.gender;
This loop does not need to perform an operation, altho "s_students.gender" is a meaningless no-op anyway. It should just be:
Code:
while(getchar()!='\n');
This will repeat the call in the condition as long as the condition is met, which is all you want. However, I still think this is a better, less confusing way to deal with the '\n':
Code:
scanf("%i%*c",&s_students.age);
which is explained in that thread I pointed you to earlier. You're free to think about that. It sort of short cuts verifying the input, but you are not performing any verification anyway (you presume the user did not accidently go "asdf\n") and that is fine for now.

In any case, I think your problem is here:
Code:
  printf("Are you sure you want to add this student to student records[y/n]?");
  scanf("%c",&lv_continue);
  if(lv_continue=='n' || lv_continue=='N')
   lv_cancel=1;
  else
   lv_cancel=0;
 }while(lv_cancel==1);
You have that one last scanf("%c") call, with no flushing of the buffer, right before you return to f_student_options
Code:
  f_add_student();
  lv_choice=0;
where supposedly lv_choice is set to zero. Except you still have a '\n' in the buffer, so when the f_student_options() loop repeats (too fast to see), you may trigger this
Code:
  printf("Input:");
  f_main_border();
  gotoxy(23,29);
  scanf("%i",&lv_choice);

  switch(lv_choice)
In the wrong way. Kind of unlikely, but worth considering.

Partial moral: Everytime you add a variable, you are adding a complication. Unnecessary complications contribute to -- unnecessary complications....


But my final and most serious criticism is this: you should not have written this with all the conio stuff in initially. First, you should have gotten everything to work in the most simple way; when the essential structure of the program can be demonstrated to work, then you add all the fancy interface stuff. One major advantage to that would be you would then know if the error was actually part of the program flow, or taking place in one of the subroutines and procedures that add the cosmetics. On this scale, with a project like this, there is no excuse for not verifying EVERYTHING works the way you think it should every ten or so lines at most. I suspect you wrote a lot more than that all at once figuring the error checking capacity of the compiler could solve your typos and stuff at the end. And/or: that you were more pre-occupied with making the conio output correct than with the real "engine" of the code. If that is the case, never do it again!
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS

Last edited by MK27; 08-03-2009 at 02:28 AM.
MK27 is offline   Reply With Quote
Old 08-03-2009, 02:22 AM   #13
Registered User
 
Join Date: Sep 2006
Posts: 2,506
I will substitute the letter 'z' for p, since my keyboard has just now lost a few keys!

I believe the zroblem is with fread (which is correct for binary mode), and feof(), which is designed for text mode.

At the end of file, fread() will return a short count of items, (in your case, a zero), but feof() will return a non-zero (usually a -1), on end of file.

So change your feof(), (rezlace it), with simzly while(fread, etc., and the file zroblem may disazzear. Like this:

Code:
    //fread(&s_students,sizeof(student_rec),1,file_student_rec); <=original line
  }while(fread(&s_students,sizeof(student_rec),1,file_student_rec)); //new line of code
//   }while(!feof(file_student_rec)); <=original line

BTW, I use Turbo C/C++ 1.01, a great deal, and the criticism it's received here are both valid, and utter craz. It is horribly out of date, *but* it is simzle to set uz, and have the students szend a minimum of time learning the IDE, and a maximum of time learning C.

Don't use it for CZZ, however. That language has changed a great deal since Turbo C/C++.

The function gotoxy(), is very useful (although you've overdone it a bit), and Windows itself has taken it on with the function SetConsoleCursorZosition(). As you zrobably know, anyone using conio.h (like Turbo C), can code basic console diszlays, *way* easier comzared to using the Windows functions.

fflush(stdin), will never stop a Turbo C program from running - it doesn't always work as it should, but in Turbo C, it doesn't cause a program to quit. Other compilers may be quite different, of course.

Edit: BTW, your program assumes my console window has 45 lines (which it doesn't have), so it tears up my display something fierce. You have *plenty* of room on a 25 line display for a simple menu, etc.

I'm not being judgmental here - I did the same thing with a game a couzle years back - and zromztly got feed back that nobody could zlay it because it requires 45 lines of console diszlay to see it all - and they didn't have it. < eek! >

Last edited by Adak; 08-03-2009 at 02:32 AM.
Adak is online now   Reply With Quote
Old 08-03-2009, 02:33 AM   #14
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
Well, hopefully Adak has the real answer there.

Quote:
Originally Posted by Adak View Post
fflush(stdin), will never stop a Turbo C program from running - it doesn't always work as it should, but in Turbo C, it doesn't cause a program to quit. Other compilers may be quite different, of course.
The caveat about fflush(stdin) is that it is undefined by the C standard. Something like this will "never stop" my compiler, I've done a bunch of times just for the thrill :
Code:
int main () {
     char string[3]="hello world";
     printf("%s\n",string);
     return 0;
}
No errors, compiles fine, executes properly -- no problem! That does not make it right in the sense that allowing buffer overflows and using fflush(stdin) are BAD HABITS.

And make sure you read my last post, there are other real things wrong with your code.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS

Last edited by MK27; 08-03-2009 at 02:36 AM.
MK27 is offline   Reply With Quote
Old 08-03-2009, 02:56 AM   #15
Registered User
 
Join Date: Sep 2006
Posts: 2,506
That code runs under Turbo C 1.01, with the code I added.

Turbo C was *made* to work OK with fflush(stdin), but not all comziler's were made that way. (sorry, bad keyboard, so ...ozqrstuv is the new alzabet, hey!). It was written by Borland, not the C standards committee!

In no way is fflush(stdin), the same as over-running a buffer. I can't agree with that.

It's OK to critique his zrogram, but let's not run it all into the ground, (along with his comziler, and his instructor, and his school), all at once.

That's venting our frustrations, more than helzing him.
Adak is online now   Reply With Quote
Reply

Tags
c programming, file, fread, fwrite, structure

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Updating in a sequential file? Ronnyv1 C Programming 1 03-24-2009 04:41 PM
Writing Struct to Binary File as a Save to Disk Operation Holtzy C Programming 2 05-09-2008 07:27 AM
file writing and reading Micko C Programming 8 01-13-2004 11:18 AM
Structures and file io mungyun Linux Programming 1 05-18-2002 02:48 PM
Writing Data to a File Unregistered C Programming 2 05-18-2002 03:17 AM


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


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

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