(Newbie) My Loop Isn't Looping - Aargh! 
Author Message
 (Newbie) My Loop Isn't Looping - Aargh!

Hello...

I really hope this question isn't as stupid as I have the sinking feeling
it might be, but I'm willing to look like a fool at this point, after
forty-two straight hours of working on this.  (As you might guess, I'm a
novice at both C and programming.)

This is a small program that refers to an already-created .dat file of
ten student records.  The program should go through and print these ten
records out in order, then die gracefully.  Instead, it's printing out
just the first record in the dat file ten times.  

I know I'm doing something wrong, and I know it must be something simple,
but at this point I've gone through the book three or four times and
tried many different things with no success.  (I'm attempting to learn C
from a free online course and a couple of textbooks a friend was generous
enough to give me.)

Any help that anyone can offer will be accepted with crawling, groveling
gratitude.  Code follows.

Thanks,

Trou

#include <stdio.h>
#include <string.h>

        struct record /*student record structure */
        {
                char fname[16];
                char lname[16];
                char id[8];
                char street[31];
                char city[11];
                char state[3];
                char zip[10];
                char ssn[10];
                char major[5];
                int credits;
        };
        FILE *myfile;

 /* function to read student records - 23 */
        struct record read_record (int c)
        {
                struct record student_file[10];
            char buffer[255];
                /*int c; counter */

        myfile = fopen ("roster.dat", "r");

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].fname, buffer, 15);
    student_file[c].fname[15]='\0';
        /*printf ("test fname: %s \n", student_file[c].fname); */

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].lname, buffer, 15);
    student_file[c].lname[15]='\0';
        /*40 printf ("test lname: %s \n", student_file[c].lname);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].id, buffer, 7);
    student_file[c].id[7]='\0';
        /*printf ("test id: %s \n", student_file[c].id);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].street, buffer, 30);
    student_file[c].street[30]='\0';
        /*50 printf ("test street address: %s \n",
student_file[c].street);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].city, buffer, 10);
    student_file[c].city[10]='\0';
        /*printf ("test city address: %s \n", student_file[c].city);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].state, buffer, 2);
    student_file[c].state[2]='\0';
        /*60 printf ("test state address: %s \n",
student_file[c].state);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].zip, buffer, 9);
    student_file[c].zip[9]='\0';
        /*printf ("test zip: %s \n", student_file[c].zip);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].ssn, buffer, 9);
    student_file[c].ssn[9]='\0';
        /*70 printf ("test ssn: %s \n", student_file[c].ssn);*/

        fgets (buffer, 254, myfile);
        strncpy (student_file[c].major, buffer, 4);
    student_file[c].major[4]='\0';
        /*printf ("%s \n", student_file[c].major);*/

        fscanf (myfile, "%d", &student_file[c].credits);
        /*80 printf ("%d \n", student_file[c].credits);*/

        fclose (myfile);
        return (student_file[c]);
        }

void main ()
{
        struct record student_records[10];
        int x;
        int y;

        for (x=0; x<10; ++x)
        {
                student_records[x] = read_record (x);

                printf ("Student Record Number %i \n", y);
                printf ("Student's first name: %s \n",
student_records[x].fname);
                printf ("Student's last name: %s \n",
student_records[x].lname);
                printf ("Student's ID number: %s \n",
student_records[x].id);
                printf ("Student's street address: %s \n",
student_records[x].street);
                printf ("Student's city address: %s %s %s \n",
student_records[x].city, student_records[x].state,
student_records[x].zip);
                printf ("Student's SSN: %s \n", student_records[x].ssn);
                printf ("Student's major: %s \n",
student_records[x].major);
                printf ("Student's credits: %d \n",
student_records[x].credits);
                printf ("\n");
                y=x+1;
        printf ("x value: %i \n", x);
        }

Quote:
}



Fri, 26 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!

Quote:

> This is a small program that refers to an already-created .dat file of
> ten student records.  The program should go through and print these ten
> records out in order, then die gracefully.  Instead, it's printing out
> just the first record in the dat file ten times.
> void main ()
> {
> struct record student_records[10];
> int x;
> int y;

> for (x=0; x<10; ++x)
blah blah
> }

the above could be your error. what is happening is you're opening the file
and reading in the first record and in that procedure you're closing the
file as well. so when u call to read the second record it opens the file
again and AGAIN reads in the first record.

what u could do is open and close the file in the main procedure. this way
it is opened only once and closed only once. as it is now, it is opened 10
times and closed 10 times.

riyaz



Fri, 26 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!

Two things:

Quote:
>  /* function to read student records - 23 */
>    struct record read_record (int c)
>    {

    /* ... */

Quote:
>    myfile = fopen ("roster.dat", "r");

    /* ... */

Quote:
>    fclose (myfile);

If you open and close the file for every record you'll always only
read the first record. Open the file in main() and pass the handle
of the open file to the function. After all is read close the file
in main().

Quote:
> void main ()

This is forbidden. ANSI/ISO states main() always returns int. You
might also want to put a `void' into the parentheses to state your
main() takes no arguments - the way you did it implies any parameter
list for calling main() is allowed.

Cheers,

Herbert

--
#define S "Goodbye!\n"                                            
main(){exit(printf(S) != strlen(S) ? 0 : 1);}              



Fri, 26 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!
The Wrong Trousers schrieb:

Quote:

> Hello...

Hi "The Wrong Trousers",

Quote:
> I really hope this question isn't as stupid as I have the sinking feeling
> it might be, but I'm willing to look like a fool at this point, after
> forty-two straight hours of working on this.  (As you might guess, I'm a
> novice at both C and programming.)

I hope my answer reaches you before spending another two days on the
problem :-) It's not a big deal and easy to fix. I've mixed a bit of
additional advice in the hope that you might find it useful.

Quote:
> This is a small program that refers to an already-created .dat file of
> ten student records.  The program should go through and print these ten
> records out in order, then die gracefully.  Instead, it's printing out
> just the first record in the dat file ten times.

The root of the problem is, that "fopen()" makes a file available to your
program and places the read pointer firmly at the beginning of the file.
when you open for reading you *always* start at the first byte of the
file. That's why you read the same stuff 10 times.

Simple solution: open the file *outside* of the loop and pass the "FILE*"
to the "read_record" function as a parameter

One general observation: the indentation of your code looks really
horrible in the posted form. This might be due to your use of the "TAB"
character in the source code. If so, you should do a conversion (TAB to
spaces) before posting source code.

Quote:
>         struct record /*student record structure */
>         {
>                 char fname[16];
>                 char lname[16];
>                 char id[8];
>                 char street[31];
>                 char city[11];
>                 char state[3];
>                 char zip[10];
>                 char ssn[10];
>                 char major[5];
>                 int credits;
>         };

It is a good idea to use macros for maximum array sizes. This enhances the
maintainability (and quite often the readability) of the code. Example:

   #define MAX_FILENAME 16
   #define MAX_LASTNAME 16
   #define MAX_ID       8

Quote:
>         FILE *myfile;

This can safely be made a local variable in "main()".

Quote:
>  /* function to read student records - 23 */
>         struct record read_record (int c)
>         {

To pass in the file as a parameter use:
    struct record read_record( FILE *myfile, int c )

Quote:
>                 struct record student_file[10];

This function is supposed to read a *single* student record. Therefore you
do not need an array here. A single record will do:
   struct record myStudent;

Quote:
>             char buffer[255];
>                 /*int c; counter */

>         myfile = fopen ("roster.dat", "r");

This does not belong here. It should be done by the calling function
*before* the loop. And you should *NEVER* forget to check the return value
of "fopen()" against NULL !

Quote:
>         fgets (buffer, 254, myfile);

The "fgets()" function can return an error status that you should not
neglect to check:
   result = fgets (buffer, 254, myfile);
   if ( result == NULL )
   {
      /* handle file I/O error here */
   }

Quote:
>         strncpy (student_file[c].fname, buffer, 15);
>     student_file[c].fname[15]='\0';

Two things to note: 1) you have commented out "c" above and 2) this is a
good place for using the macros ones you have defined them:
   strncpy( myStudent.fname, buffer, MAX_FILENAME );
   myStudent.fname[MAX_FILENAME-1]='\0';

[biggish SNIP]

Quote:
>         fclose (myfile);

Soem as with "fopen()": close the function in the calling function after
the loop.

Quote:
>         return (student_file[c]);

This will of course become:
   return myStudent;

Quote:
>         }

> void main ()

The only real correct return type for "main()" is "int". Some compilers
allow "void", but it is not portable and it is not ANSI-C. The correct
equivalent form would be:
   int main( void )

Quote:
> {

[more snippage]

Now *you* apply the changes, that I mentioned in my comments,  to the
"main()" function ;-) But do ask again if it should not work as expected.

--
Stephan
initiator of the campaign against grumpiness in c.l.c
fight the bug, read the FAQ: http://www.eskimo.com/~scs/C-faq/top.htm



Fri, 26 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!
Hello,
   The basic problem is that you aren't paying attention to the data writing
program.
As data reading program shows you must be using fputs statement to write the
data stucture to the file. Now if you will open the data file you will see
all the data arranged in a line with no specific length now when you read
first 254 bytes with this progam it reads the data as string and not as a
structure. Firstly you should use fread and fwrite command to read and write
to data file .. I am writing a small code to show its usage.

#include "stdio.h"
#include "string.h"
int main(void)
{
struct record {
char name[15];
char id[15];

Quote:
}record1;

FILE * in;
struct record * recordptr;
gets(record1.name);
gets(record1.id);
in=fopen("data.dat","r+");
recordptr=&record1;
fwrite(recordptr,sizeof (struct record), 1,in);
fclose(in);
in=fopen("data.dat","r+");
fread(recordptr,sizeof (struct record),1,in);
printf("%s",record1.name);
printf("%s",record1.id);
return 0;
Quote:
}

secondly .. if at all you are determined to make use of fgets and fputs
..then you had to do one thing... you had to write "\n" to file after every
fputs
{.......
char *enter= "\n";
fputs(data1,n);
fputs(enter,in);
fputs(data2,in);
fputs(enter,in);
..............
thirdly ... you are reading data into a buffer of 255 bytes which is not at
allrequired over here but it is only eating memory and unnecessay confusion
..why the hell you areusing strncpy and the command after it these are all
useless

Quote:
> fgets (buffer, 254, myfile);
> strncpy (student_file[c].fname, buffer, 15);
>     student_file[c].fname[15]='\0';
> /*printf ("test fname: %s \n", student_file[c].fname); */

this work can be done in only one line

fgets(student_file[c].fname, sizeof(student_file[c].fname),myfile);

one important thing to clearify at this point is the use of strlen and
sizeof ...
u cannot use strlen because it gives size of the current string and
currently no data is present in the structure so you just cannot use strlen
where as sizeof tell the size of the current element and so we had to make
use of it to get the correct size.

fourthly .. you had made use of y in your main with out initializing it to
zero ....well you had defined an auto variable and it is not initialized to
zero automatically but retain in memory either use the word static or
initialize it manually to zero
static int y;

After reading this please reply me back,  I am having problem with this
e-mail account, so that I can assure that you had got the reply. If you need
to know anything else please let me know.

Bye
Ashish



Quote:
> Hello...

> I really hope this question isn't as stupid as I have the sinking feeling
> it might be, but I'm willing to look like a fool at this point, after
> forty-two straight hours of working on this.  (As you might guess, I'm a
> novice at both C and programming.)

> This is a small program that refers to an already-created .dat file of
> ten student records.  The program should go through and print these ten
> records out in order, then die gracefully.  Instead, it's printing out
> just the first record in the dat file ten times.

> I know I'm doing something wrong, and I know it must be something simple,
> but at this point I've gone through the book three or four times and
> tried many different things with no success.  (I'm attempting to learn C
> from a free online course and a couple of textbooks a friend was generous
> enough to give me.)

> Any help that anyone can offer will be accepted with crawling, groveling
> gratitude.  Code follows.

> Thanks,

> Trou

> #include <stdio.h>
> #include <string.h>

> struct record /*student record structure */
> {
> char fname[16];
> char lname[16];
> char id[8];
> char street[31];
> char city[11];
> char state[3];
> char zip[10];
> char ssn[10];
> char major[5];
> int credits;
> };
> FILE *myfile;

>  /* function to read student records - 23 */
> struct record read_record (int c)
> {
> struct record student_file[10];
>     char buffer[255];
> /*int c; counter */

> myfile = fopen ("roster.dat", "r");

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].fname, buffer, 15);
>     student_file[c].fname[15]='\0';
> /*printf ("test fname: %s \n", student_file[c].fname); */

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].lname, buffer, 15);
>     student_file[c].lname[15]='\0';
> /*40 printf ("test lname: %s \n", student_file[c].lname);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].id, buffer, 7);
>     student_file[c].id[7]='\0';
> /*printf ("test id: %s \n", student_file[c].id);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].street, buffer, 30);
>     student_file[c].street[30]='\0';
> /*50 printf ("test street address: %s \n",
> student_file[c].street);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].city, buffer, 10);
>     student_file[c].city[10]='\0';
> /*printf ("test city address: %s \n", student_file[c].city);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].state, buffer, 2);
>     student_file[c].state[2]='\0';
> /*60 printf ("test state address: %s \n",
> student_file[c].state);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].zip, buffer, 9);
>     student_file[c].zip[9]='\0';
> /*printf ("test zip: %s \n", student_file[c].zip);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].ssn, buffer, 9);
>     student_file[c].ssn[9]='\0';
> /*70 printf ("test ssn: %s \n", student_file[c].ssn);*/

> fgets (buffer, 254, myfile);
> strncpy (student_file[c].major, buffer, 4);
>     student_file[c].major[4]='\0';
> /*printf ("%s \n", student_file[c].major);*/

> fscanf (myfile, "%d", &student_file[c].credits);
> /*80 printf ("%d \n", student_file[c].credits);*/

> fclose (myfile);
> return (student_file[c]);
> }

> void main ()
> {
> struct record student_records[10];
> int x;
> int y;

> for (x=0; x<10; ++x)
> {
> student_records[x] = read_record (x);

> printf ("Student Record Number %i \n", y);
> printf ("Student's first name: %s \n",
> student_records[x].fname);
> printf ("Student's last name: %s \n",
> student_records[x].lname);
> printf ("Student's ID number: %s \n",
> student_records[x].id);
> printf ("Student's street address: %s \n",
> student_records[x].street);
> printf ("Student's city address: %s %s %s \n",
> student_records[x].city, student_records[x].state,
> student_records[x].zip);
> printf ("Student's SSN: %s \n", student_records[x].ssn);
> printf ("Student's major: %s \n",
> student_records[x].major);
> printf ("Student's credits: %d \n",
> student_records[x].credits);
> printf ("\n");
> y=x+1;
> printf ("x value: %i \n", x);
> }
> }



Fri, 26 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!
[snip]

Quote:
> #include "stdio.h"
> #include "string.h"

Use the proper <> forms.

Quote:
> int main(void)
> {
> struct record {
> char name[15];
> char id[15];
> }record1;
> FILE * in;
> struct record * recordptr;

Adopt or develop a coding style.

Quote:
> gets(record1.name);
> gets(record1.id);

Never use gets(). Never tell anyone to use gets().

Quote:
> in=fopen("data.dat","r+");

Check for NULL.

Quote:
> recordptr=&record1;
> fwrite(recordptr,sizeof (struct record), 1,in);
> fclose(in);
> in=fopen("data.dat","r+");
> fread(recordptr,sizeof (struct record),1,in);

recordptr is redundant.

Quote:
> printf("%s",record1.name);
> printf("%s",record1.id);
> return 0;
> }
[snip]
> > fgets (buffer, 254, myfile);
> > strncpy (student_file[c].fname, buffer, 15);
> >     student_file[c].fname[15]='\0';
> > /*printf ("test fname: %s \n", student_file[c].fname); */
> this work can be done in only one line

> fgets(student_file[c].fname, sizeof(student_file[c].fname),myfile);

His code removes the newline that might be hiding in the string.
[snip rest]

Gergo

--
The fortune program is supported, in part, by user contributions and by
a major grant from the National Endowment for the Inanities.

GU d- s:+ a--- C++>$ UL+++ P>++ L+++ E>++ W+ N++ o? K- w--- !O !M !V
PS+ PE+ Y+ PGP+ t* 5+ X- R>+ tv++ b+>+++ DI+ D+ G>++ e* h! !r !y+



Fri, 26 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!


<snip>

Quote:

> This is a small program that refers to an already-created .dat file of
> ten student records.  The program should go through and print these
> ten records out in order, then die gracefully.  Instead, it's printing
> out just the first record in the dat file ten times.

<snip>

other posters have have pointed out your major errors- repeatedly
re-opening the file and void main().

Quote:

> #include <stdio.h>
> #include <string.h>

>    struct record /*student record structure */
>    {
>            char fname[16];
>            char lname[16];
>            char id[8];
>            char street[31];
>            char city[11];
>            char state[3];
>            char zip[10];
>            char ssn[10];
>            char major[5];
>            int credits;
>    };
>    FILE *myfile;

>  /* function to read student records - 23 */
>    struct record read_record (int c)
>    {
>            struct record student_file[10];
>        char buffer[255];
>            /*int c; counter */

>    myfile = fopen ("roster.dat", "r");

>    fgets (buffer, 254, myfile);

this reads the first line of the file

Quote:
>    strncpy (student_file[c].fname, buffer, 15);
>     student_file[c].fname[15]='\0';

you don't need to do this. strncpy() should terminate the string.

Quote:
>    /*printf ("test fname: %s \n", student_file[c].fname); */

>    fgets (buffer, 254, myfile);

this reads the second line of the file. I don't think you meant to do
that did you...

Quote:
>    strncpy (student_file[c].lname, buffer, 15);
>     student_file[c].lname[15]='\0';
>    /*40 printf ("test lname: %s \n", student_file[c].lname);*/

>    fgets (buffer, 254, myfile);

etc. etc.

Quote:
>    strncpy (student_file[c].id, buffer, 7);
>     student_file[c].id[7]='\0';
>    /*printf ("test id: %s \n", student_file[c].id);*/

<snip>

I'm curious, how come your diagnostic printf()s show you what was going
on?

--
Both the tractability and the invisibility of the software product
expose its builders to perpetual changes in requirements...
                -- Brookes

Sent via Deja.com http://www.deja.com/
Before you buy.



Sat, 27 Apr 2002 03:00:00 GMT  
 (Newbie) My Loop Isn't Looping - Aargh!

Quote:
>> strncpy (student_file[c].fname, buffer, 15);
>>     student_file[c].fname[15]='\0';

>you don't need to do this. strncpy() should terminate the string.

AFAIK, what you said is correct concerning strncat(), but strncpy() will not
add the final 0 if the maximum length is reached. IMO, this is a
specification-bug of the C-RTL.

--
HS
C- FAQ: http://www.eskimo.com/~scs/C-faq/top.html
About gets() and fflush(stdin) :
- "Even Buffy cannot slay the resulting RhinoDaemons."
Martin Ambuhl clc.



Sat, 27 Apr 2002 03:00:00 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Loop logic isn't working correctly

2. isn't do-while loop better?

3. newbie's answer to two nested for loops question

4. newbie's answer to two nested for loops problem

5. For loops into for loops

6. Loop or Loops in "C"

7. SEMA - WHILE loop in a FOR loop !

8. For loops into for loops

9. wanted - C and/or Fortran source for 24-loop Livermore Loops

10. process loops but 'context' doesn't show me where it loops

11. Curious 'while' loop

12. NULL isn't 0/0 isn't NULL

 

 
Powered by phpBB® Forum Software