Solved

fwrite garbage output

Posted on 2007-04-01
96
668 Views
Last Modified: 2008-03-10
I have some code to make a random access file but when I read the output back all I get is garbage symbols

here is the code:
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZ 256


struct hardware
          {
            int toolId;
            int quantity;
          float cost;
          char toolName[BUFSIZ];

        };

int main()
{

struct hardware list[]={
{5, 7, 57.98,"name 1"},
{9, 76, 11.99,"name 2"},
{11, 12, 11.00,"name 3"}
};

FILE *fp = fopen ("hardware.dat","wb");

       if (fp==NULL)

       {
                fprintf(stderr, "Error reading file\n");
             
                exit(EXIT_FAILURE);
       }
         else
         {

                    for (int i = 1; i <= 50; i++ )
                        fwrite( &list,  sizeof(struct hardware ), 1, fp );

                    fclose (fp);      
         }

  return 0;
}
Can anyone tell me why
0
Comment
Question by:sassy4sure
  • 49
  • 46
96 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 18832939
>> but when I read the output back all I get is garbage symbols

Can you show the code where you read it back ?

btw : this :

                    for (int i = 1; i <= 50; i++ )
                        fwrite( &list,  sizeof(struct hardware ), 1, fp );

writes the first element from the array 50 times in the file. I'm not sure that that was what you intended.
0
 

Author Comment

by:sassy4sure
ID: 18833000
I meant when I checked the data file. So If I wanted to write the whole array could I leave off the for?
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 50 total points
ID: 18833012
>> I meant when I checked the data file.

That's normal : you wrote a binary file.


>> So If I wanted to write the whole array could I leave off the for?

                        fwrite( &list,  sizeof(struct hardware ), 3, fp );

Notice the 3 : that will write the first 3 elements from the array into the file. No need for the for loop.
0
 

Author Comment

by:sassy4sure
ID: 18833031
ok, i thought so, but then how do i check what was written to the file?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18833036
>>  ok, i thought so, but then how do i check what was written to the file?

You can use fread in a similar way as you used fwrite.
0
 

Author Comment

by:sassy4sure
ID: 18833102
getting the error  must have class/struct/union with this:

fread( &list, sizeof( struct hardware ), 4, fp );
printf( "%-6d%-16d%10.2f%-11s\n",list.toolId, list.quantity, list.cost, list.toolName );
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18833291
list is an array, so try this :

    int i = 0;
    for (i = 0; i < 4; ++i) {
      printf( "%-6d%-16d%10.2f%-11s\n",list[i].toolId, list[i].quantity, list[i].cost, list[i].toolName );
    }
0
 

Author Comment

by:sassy4sure
ID: 18833996
Nope, the output is still not right a series of lines and negative numbers
0
 

Author Comment

by:sassy4sure
ID: 18834079
is there an easier way to populate a dat file with test data? I was trying to do it this way because the one i made in note pad wasn't working when i tried to find a specific record i figured the data needed to be structured
0
 
LVL 84

Expert Comment

by:ozo
ID: 18834170
How did you read the output back?
was it something like fread( &list, sizeof( struct hardware ), 1, fp )?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18834472
Can you show both programs you used please ? (completely)
0
 

Author Comment

by:sassy4sure
ID: 18835450
Here is the program that creates the structure for the file i want to use
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZ 256


struct hardware
          {
            int toolId;
            int quantity;
                  float cost;
                  char toolName[BUFSIZ];

        };

int main()
{

struct hardware list[]={
{5, 7, 57.98,"Electronic Sander"},
{9, 76, 11.99,"Hammer"},
{11, 12, 11.00,"Jig saw"},
{2, 0,79.50,"Lawn mower"}
};

FILE *fp = fopen ("hardware.dat","wb");

       if (fp==NULL)

       {
                fprintf(stderr, "Error reading file\n");
             
                exit(EXIT_FAILURE);
       }
         else
         {
     
                        fwrite( &list,  sizeof(struct hardware ), 4, fp );
                        printf( "%-6d%-16d%10.2f%-11s\n", "Tool ID No.", "Quantity","Cost", "Tool Name" );

     
                fread( &list, sizeof( struct hardware ), 4, fp );

                        int i = 0;
                        for (i = 0; i < 4; ++i) {
                        printf( "%-6d%-16d%10.2f%-11s\n",list[i].toolId, list[i].quantity, list[i].cost, list[i].toolName );
   
                    fclose (fp);      
                        }
         }

  return 0;
         }
0
 

Author Comment

by:sassy4sure
ID: 18835489
/*This Function updates the information in the cost and quantity field*/
void update(void)
{
  struct hardware tool;
  int toolnum;
  FILE *fp;

if ( ( fp = fopen( "newhardware.dat", "r+" ) ) == NULL )
      printf( "File could not be opened.\n" );
else


printf("Enter the Record Number to update (1 - 50): ");
scanf("%d", &toolnum);

        fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET);

        fread(&tool, sizeof(struct hardware), 1, fp);

        if(tool.toolId == 0)
                printf("\tTool Id #%d has no information.\n",toolnum);
        else
        {
                printf("\t\t%-7s%-19s%-8s%9.2s\n",
                        "Part#", "Tool name", "Quantity","Cost");
                printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId,
                        tool.toolName, tool.quantity,tool.cost);
            }
//give choice to update the field
}
The problem with this is when i search the manual notepad file the record isn't turning up in fact no matter what id i put in i get 2 and some zeros which is of course wrong
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18835513
No. If you want to read the file within the same program, you'll have to rewind the stream first.

Here's the modified code :



#include <stdio.h>
#include <stdlib.h>
#define BUFSIZ 256

struct hardware {
  int toolId;
  int quantity;
  float cost;
  char toolName[BUFSIZ];
};

int main() {
  struct hardware list[] = {
    {5, 7, 57.98,"Electronic Sander"},
    {9, 76, 11.99,"Hammer"},
    {11, 12, 11.00,"Jig saw"},
    {2, 0,79.50,"Lawn mower"}
  };

  FILE *fp = fopen ("hardware.dat","w+b");  /* <-- you want to write AND read */

  if (fp==NULL) {
    fprintf(stderr, "Error reading file\n");
    exit(EXIT_FAILURE);
  }
  else {
    int i = 0;  /* <-- variable declarations have to be at the beginning of a block in C */

    fwrite( &list,  sizeof(struct hardware ), 4, fp );

    printf( "%-6d%-16d%10.2f%-11s\n", "Tool ID No.", "Quantity","Cost", "Tool Name" );

    rewind(fp);  /* <-- rewind the file stream */

    fread( &list, sizeof( struct hardware ), 4, fp );

    i = 0;
    for (i = 0; i < 4; ++i) {
      printf( "%-6d%-16d%10.2f%-11s\n",list[i].toolId, list[i].quantity, list[i].cost, list[i].toolName );
    }
    fclose (fp);  /* <-- this has to be outside of the for loop ! */
  }

  return 0;
}


Read the comments I added to understand what I changed and why.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18835550
And here are a few modifications to your update function. Read my comments to get more info on the modifications I did :


/*This Function updates the information in the cost and quantity field*/
void update(void) {
    struct hardware tool;
    int toolnum;
    FILE *fp;

    if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL )      /* <-- we want to read in binary mode */
        printf( "File could not be opened.\n" );
    else {    /* <-- you forgot the {} around the else block */
        printf("Enter the Record Number to update (1 - 50): ");
        scanf("%d", &toolnum);

        fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET);

        fread(&tool, sizeof(struct hardware), 1, fp);

        if(tool.toolId == 0)
            printf("\tTool Id #%d has no information.\n",toolnum);
        else {
            printf("\t\t%-7s%-19s%-8s%9.2s\n", "Part#", "Tool name", "Quantity","Cost");
            printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
        }
        //give choice to update the field
    }
}
0
 

Author Comment

by:sassy4sure
ID: 18835642
There is output for the  list, finally but why can't i see the labels?

printf( "%-6d%-16d%10.2f%-11s\n", "Tool ID No.", "Quantity","Cost", "Tool Name" );

I know it is not important as it is not written to the file but I would like to know for future reference.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18835703
>> printf( "%-6d%-16d%10.2f%-11s\n", "Tool ID No.", "Quantity","Cost", "Tool Name" );

You pass 4 strings to the printf, so the format string has to use %s 4 times :

    printf( "%-6s%-16s%-10s%-11s\n", "Tool ID No.", "Quantity","Cost", "Tool Name" );
0
 

Author Comment

by:sassy4sure
ID: 18835796
Ok, thanks I'll try the  new file with the above function and see if it works
0
 

Author Comment

by:sassy4sure
ID: 18835908
getting the same ouput so maybe it wasn't the file after all am I using the correct search method
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18835926
Can you describe what you did ?
What does the file contain ?
What output do you get ?
0
 

Author Comment

by:sassy4sure
ID: 18836019
I first used a txt file manually done in notepad with the same list. When i tried to use it tofind a record to update the file I got nothing
Thinking it was the file i created another program to make a structured list but now i'm getting the same output the function is above.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18836061
>> I first used a txt file manually done in notepad with the same list.

How did you create that ?

Try these two simple programs. Use the first to create the file, and then run the second to read the file :

----  program 1 : create the file  ----

#include <stdio.h>
#include <stdlib.h>
#define BUFSIZ 256

struct hardware {
  int toolId;
  int quantity;
  float cost;
  char toolName[BUFSIZ];
};

int main() {
  struct hardware list[] = {
    {5, 7, 57.98,"Electronic Sander"},
    {9, 76, 11.99,"Hammer"},
    {11, 12, 11.00,"Jig saw"},
    {2, 0,79.50,"Lawn mower"}
  };

  FILE *fp = fopen ("hardware.dat","wb");

  if (fp==NULL) {
    fprintf(stderr, "Error reading file\n");
    exit(EXIT_FAILURE);
  }
  else {
    fwrite( &list,  sizeof(struct hardware ), 4, fp );
    fclose(fp);
  }

  return 0;
}



---- program 2 : read the file ----

#include <stdio.h>
#include <stdlib.h>
#define BUFSIZ 256

struct hardware {
  int toolId;
  int quantity;
  float cost;
  char toolName[BUFSIZ];
};

int main() {
  struct hardware list[4] = { 0 };

  FILE *fp = fopen ("hardware.dat","rb");

  if (fp==NULL) {
    fprintf(stderr, "Error reading file\n");
    exit(EXIT_FAILURE);
  }
  else {
    int i = 0;

    printf( "%-6s%-16s%-10s%-11s\n", "Tool ID No.", "Quantity","Cost", "Tool Name" );

    fread( &list, sizeof( struct hardware ), 4, fp );

    i = 0;
    for (i = 0; i < 4; ++i) {
      printf( "%-6d%-16d%10.2f%-11s\n",list[i].toolId, list[i].quantity, list[i].cost, list[i].toolName );
    }
    fclose (fp);
  }

  return 0;
}
0
 

Author Comment

by:sassy4sure
ID: 18836316
Isn't this what i just did?
1)I created the file in notepad.To use in a bigger program that checks inventory
2)The program you just helped me with was supposed to create the file with a structure instead since the one made in notepad yields nothing
3) Since i used the program to create the file I used it in the bigger program with this function
/*This Function updates the information in the cost and quantity field*/
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option={0};
  FILE *fp;

if ( ( fp = fopen( "newhardware.dat", "r+" ) ) == NULL )
      printf( "File could not be opened.\n" );
else


printf("Enter the Record Number to update (1 - 50): ");
scanf("%d", &toolnum);

        fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET);

        fread(&tool, sizeof(struct hardware), 1, fp);

        if(tool.toolId == 0)
                printf("\tTool Id #%d has no information.\n",toolnum);
        else
        {
                printf("\t\t%-7s%-19s%-8s%9.2s\n",
                        "Tool Id#", "Tool name", "Quantity","Cost");
                printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId,
                        tool.toolName, tool.quantity,tool.cost);
             
                        printf("Update Tool Quantity?Y/N:\n");
                              do{
                              scanf("%c", &option);
                            toupper(option);

                           }while( (option !='Y')&&(option !='N'));
                 if(option=='Y')
                         {
                               printf("Enter New Quantity:\n");
                               scanf("%d",tool.quantity);
                         }
                         else
                         {
                        
                         
                               printf("Update Tool Cost?Y/N:\n");
                               scanf("%c", &option);

                               if(option=='Y')
                               {
                                     printf("Enter New Cost:\n");
                                     scanf("%f",tool.cost);
                               }
                         }
                        fseek(fp, (toolnum - 1) * sizeof(struct hardware), SEEK_SET);

               fwrite(&tool, sizeof(struct hardware),1, fp);
            }/*endelse*/
      fclose(fp);
            
}
But no dice, Do you understand what i am trying to do?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18836451
>> 1)I created the file in notepad.

That won't work as I already said : you're trying to read it in binary mode, so you have to create it in binary mode (ie. it has to contain memory dumps of the structs).


>> 3) Since i used the program to create the file I used it in the bigger program with this function

You didn't make the modifications I suggested earlier ...


>> Isn't this what i just did?

Just try it, and see if it works. Create two new projects - one for each program - and run them one by one (make sure that the second can find the file generated by the first).
If it works, you can simply look for differences with your code.
0
 

Author Comment

by:sassy4sure
ID: 18836537
ok, it works(so did mine)  but I am not trying to display all of the  file just the one the user enters the id for
1)This is not happening
2)If i enter one that doesn't exist there is no error catching
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18836626
>> (so did mine)

Ok, sorry - i didn't get that - my apologies


>> just the one the user enters the id for
>> 1)This is not happening

Did you make the modifications to the function I suggested earlier (note that in your last post I didn't see these) ? If so, and it still doesn't do what you expect, can you post a bit more code (how the function gets called), as well as what output you get ?

btw, did you check that the file was created successfully by using a working program to read it ?


>> 2)If i enter one that doesn't exist there is no error catching

fseek() returns a non-zero value in case of a problem :

http://www.cplusplus.com/fseek

So, if the fseek() didn't succeed, you can easily know that, and handle it appropriately.
0
 

Author Comment

by:sassy4sure
ID: 18836787
Are you saying that since the structure is an array i should use the for? How would I do that if I only wish to display one record?
by error checking  I meant:

if(tool.toolId == 0)
                printf("\tTool Id #%d has no information.\n",toolnum);

To check if the id is there am i using the correct methods?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18836976
>> Are you saying that since the structure is an array i should use the for?

??? I did not mention a for loop ???

Let me post the modifications I made to your function again - you might have overlooked them (read my comments !!) :


/*This Function updates the information in the cost and quantity field*/
void update(void) {
    struct hardware tool;
    int toolnum;
    FILE *fp;

    if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL )      /* <-- we want to read in binary mode */
        printf( "File could not be opened.\n" );
    else {    /* <-- you forgot the {} around the else block */
        printf("Enter the Record Number to update (1 - 50): ");
        scanf("%d", &toolnum);

        fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET);

        fread(&tool, sizeof(struct hardware), 1, fp);

        if(tool.toolId == 0)
            printf("\tTool Id #%d has no information.\n",toolnum);
        else {
            printf("\t\t%-7s%-19s%-8s%9.2s\n", "Part#", "Tool name", "Quantity","Cost");
            printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
        }
        //give choice to update the field
    }
}



>> by error checking  I meant:
>>
>> if(tool.toolId == 0)
>>                 printf("\tTool Id #%d has no information.\n",toolnum);
>>
>> To check if the id is there am i using the correct methods?

Well, you can do that, but first you have to be sure that you were actually ABLE to READ the record from the file. That's where the return values from fseek() and fread() come into play ...
0
 

Author Comment

by:sassy4sure
ID: 18837188
??? I did not mention a for loop ???
The I don't know what I should correct the methods i used to read before are the same except for that

Well, you can do that, but first you have to be sure that you were actually ABLE to READ the record from the file. That's where the return values from fseek() and fread() come into play ...
Here is the corrected function but it still doesn't work
void transfer(FILE *infile,FILE *outfile)
{
      unsigned char buffer[BUFSIZ];
      size_t BytesRead;

                  
               while((BytesRead = fread(buffer, 1, sizeof buffer,infile)) > 0)
             {
               fwrite(buffer, 1, BytesRead, outfile);
             }
           if(ferror(infile) || ferror(outfile))
             {
             printf("File write Error!\n");
             }
               fclose(infile);
               fclose(outfile);
 
}
/*This Function updates the information in the cost and quantity field*/
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option={0};
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

        if((fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET)<0))/*check for errors*/
            {
                  printf("Error reading file");
            }
            

        fread(&tool, sizeof(struct hardware), 1, fp);

        if(tool.toolId == 0)/*check if id exists*/
            {
                printf("\tTool Id #%d has no information.\n",toolnum);
            }/*endif*/
        else
        {
                printf("\t\t%-7s %-19s%-8s%9s\n",
                        "Tool Id#", "Tool name", "Quantity","Cost");
                printf("\t\t%-7d %-19s%-8d%9.2f\n",tool.toolId,
                        tool.toolName, tool.quantity,tool.cost);
             
                        printf("Update Tool Quantity?Y/N:\n");
                              do{
                              scanf("%c", &option);
                           

                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);
                         }
                         else
                         {
                               printf("Update Tool Cost?Y/N:");
                               do{
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",tool.cost);
                               }
                         }/*endelse*/
                        fseek(fp, (toolnum - 1) * sizeof(struct hardware), SEEK_SET);

               fwrite(&tool, sizeof(struct hardware),1, fp);
            }/*endelse*/
  }/*endelse*/
      fclose(fp);
            
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18837276
>>   char option={0};

Change this to either :

      char option = 0;

or :

      char option = '\0';



>>   if((fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET)<0))/*check for errors*/

Change this to :

    if(!(fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET)))/*check for errors*/

You don't just have to check for return values < 0, but for all non-zero return values.

Note that you write an error message to the screen, but after that you just continue ... you should gracefully end the function.




>> Here is the corrected function but it still doesn't work

Can you show the output you get ?
0
 

Author Comment

by:sassy4sure
ID: 18837399
Well now with the corrections the functions stops here
printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

        if(!(fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET)))/*check for errors*/

            {
                  printf("Error reading file");
                  exit(EXIT_FAILURE);
            }
so obviously the fseek is not successful but i have no idea why i am using the output file created by the program i just created
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18837989
Can you show me the output you get ? Everything (including the values you had to enter)
0
 

Author Comment

by:sassy4sure
ID: 18838141
these were the values

    {5, 7, 57.98,"Electronic Sander"},
    {9, 76, 11.99,"Hammer"},
    {11, 12, 11.00,"Jig saw"},
    {2, 0,79.50,"Lawn mower"}


except in table form So I added them to a structure using an array and created a file of it.Then I went over to my other program with this function and called the created file.
So say I needed to change tool id 5 I would enter 5 and the corresponding record should be displayed then I could update the record accordingly. I am currently seeing the error message you suggested I add to check fseek.
"Error reading file"
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18838174
>> So say I needed to change tool id 5 I would enter 5

There's only 4 tools in the file - there's no fifth !! At this prompt :

    Enter the Record Number to update (1 - 50):

The only valid values are 1 - 4
0
 

Author Comment

by:sassy4sure
ID: 18838574
By record number i meant tool id the file can contain up to 50 so it is like searching by the tool id
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18838596
Yes, but you put only 4 records in the file - so, you can only ask for the first 4.

I've asked this a few times already, but can you show the output ?
0
 

Author Comment

by:sassy4sure
ID: 18838700
Tell me what u mean by output?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18838719
>> Tell me what u mean by output?
The output of the program - what you see on the screen.
0
 

Author Comment

by:sassy4sure
ID: 18838725
Only if they are only 4 records I would still have to check the entire file There is another function that can add new records so when this occurs the file may contain up to fifty.
0
 

Author Comment

by:sassy4sure
ID: 18838734
The output of the program - what you see on the screen.

I told yo before
I am currently seeing the error message you suggested I add to check fseek.
"Error reading file"
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18838744
The first thing you should see is this :

    Enter the Record Number to update (1 - 50):

what did you fill in ?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18838754
>> Only if they are only 4 records I would still have to check the entire file There is another function that can add new records so when this occurs the file may contain up to fifty.

Yes, but in this example there are only 4 ... And the toolId does NOT correspond with their position in the file.
0
 

Author Comment

by:sassy4sure
ID: 18838938
So i change the the question to

Enter the Tool id you wish to update:
i fill in 5 corresponding to this record.

{5, 7, 57.98,"Electronic Sander"}
 
It still doesn't work either way. I need to know what is wrong.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18838986
>> I need to know what is wrong.

As I said : there are only 4 records in the file right now. The toolId does NOT correspond with the position of the record in the file.

This line :

        fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET);

looks for the record at position 5, which does NOT exist in the file.

You need to do one of these two :

1) fill up the file with 50 tools IN ORDER - ie. tool 1 comes first, then tool2, etc.

2) don't use fseek(), but iterate over all tools in the file, until you find the one with toolId 5
0
 

Author Comment

by:sassy4sure
ID: 18839201
Ok so how  do i do the latter keeping my file structure.
How do i know many records are currently in the file so when I add a new record it is less than 50 but the next number in the sequence.
why am i seeing that there was an error reading the file why is fseek unsuccessful even when I enter 2 or 3?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18839285
>> why am i seeing that there was an error reading the file why is fseek unsuccessful even when I enter 2 or 3?

Oops, that was my mistake - change this :

        if(!(fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET)))/*check for errors*/

to this :

        if(fseek(fp, (toolnum-1) * sizeof(struct hardware),SEEK_SET))/*check for errors*/



>> How do i know many records are currently in the file so when I add a new record it is less than 50 but the next number in the sequence.

You don't have to know how many there are in the file - you can just iterate over all of them and pick the right one.

Something like this :

        int found = 0;
        while (fread(&tool, sizeof(struct hardware), 1, fp)) {
            if(tool.toolId == toolnum) {
                found = 1;
                printf("\t\t%-7s%-19s%-8s%9.2s\n", "Part#", "Tool name", "Quantity","Cost");
                printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                //give choice to update the field
                break;
            }
        }
        if (!found) {
            printf("\tTool Id #%d has no information.\n",toolnum);
        }

ie. you don't use fseek().

This is only one way of doing this - you should find the way that suits you best ...
0
 

Author Comment

by:sassy4sure
ID: 18839550
Ok it works but when I try to update the Cost or quantity  I get an access violation Attempted to write to protected memory
/*This Function updates the information in the cost and quantity field*/
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
        int found = 0;
        while (fread(&tool, sizeof(struct hardware), 1, fp))
            {
            if(tool.toolId == toolnum)
                  {
                found = 1;
                printf("\t\t%-7s%-19s%-8s%9.2s\n", "Tool Id#", "Tool name", "Quantity","Cost");
                printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                        printf("Update Tool Quantity?Y/N:\n");
                              do{
                              scanf("%c", &option);
                           

                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);
                         }
                         else
                         {
                               printf("Update Tool Cost?Y/N:");
                               do{
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",tool.cost);
                               }
                         }/*endelse*/
                        break;
                  }
            }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);
       }
            
            fwrite(&tool, sizeof(struct hardware),1, fp);
  }/*endelse*/

      fclose(fp);
            
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18839769
>> Ok it works but when I try to update the Cost or quantity  I get an access violation Attempted to write to protected memory

The file pointer is just PAST the record you want to update, so you need to set it to the beginning of the record you want to modify.

btw, you should place the fwrite INSIDE the

             if(tool.toolId == toolnum) {
                 /* ... */
                 /* do the fwrite here */
             }
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:sassy4sure
ID: 18840105
Is that what you mean?If so i am getting the same error

if(tool.toolId == toolnum)
                  {
                found = 1;
                printf("\t\t%-7s%-19s%-8s%9.2s\n", "Tool Id#", "Tool name", "Quantity","Cost");
                printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                        printf("Update Tool Quantity?Y/N:\n");
                              do{
                              scanf("%c", &option);
                           

                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);

                         }
                         else
                         {
                               printf("Update Tool Cost?Y/N:");
                               do{
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",tool.cost);
                               }
                         }/*endelse*/
                     fseek(fp, (toolnum - 1) * sizeof(struct hardware), SEEK_SET);//find the beginning of record
                            fwrite(&tool, sizeof(struct hardware),1, fp); //write either cost or quantity
                        break;

                  }
            }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);
       }
            
            
  }/*endelse*/
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18841372
>>                      fseek(fp, (toolnum - 1) * sizeof(struct hardware), SEEK_SET);//find the beginning of record

No, I thought we determined that you cannot use toolnum as an index in the file ?

You just need to jump back 1 record ...

Take a look at the SEEK_CUR option :

        http://www.cplusplus.com/fseek

and realise that the offset can be negative.
0
 

Author Comment

by:sassy4sure
ID: 18841723
ok still getting a System Access Violation error attempted to read or write protected memory
 printf("Enter New Quantity:");
scanf("%d",tool.quantity);//error on this line
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18841727
>> scanf("%d",tool.quantity);//error on this line

What did you change ?

Can you show the complete function again ?
0
 

Author Comment

by:sassy4sure
ID: 18841843
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
     int found = 0;
     while (fread(&tool, sizeof(struct hardware), 1, fp))
            {
          if(tool.toolId == toolnum)
                  {
              found = 1;
              printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
              printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                    printf("Update Tool Quantity?Y/N:\n");
                          do
                              {
                                scanf("%c", &option);
                           
                        }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);
                    
                         }
                         else
                         {
                               printf("Update Tool Cost?Y/N:");
                               do
                                 {
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",tool.cost);
                               }
                         }/*endelse*/
                     fseek(fp,- 1, SEEK_CUR);
               fwrite(&tool, sizeof(struct hardware),1, fp);
                        break;

                  }
            }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);
       }
            
            
  }/*endelse*/

      fclose(fp);
            
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18841862
Change this :

    while (fread(&tool, sizeof(struct hardware), 1, fp))

to :

    while (fread(&tool, sizeof(struct hardware), 1, fp) == sizeof(struct hardware))


And this :

    fseek(fp,- 1, SEEK_CUR);

to this :

    fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
0
 

Author Comment

by:sassy4sure
ID: 18841894
now it is no longer finding the tool id and i made no other changes perhaps it is my control structures
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
     int found = 0;
     while (fread(&tool, sizeof(struct hardware), 1, fp) == sizeof(struct hardware))
            {
          if(tool.toolId == toolnum)
                  {
              found = 1;
              printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
              printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                    printf("Update Tool Quantity?Y/N:");
                          do
                              {
                                scanf("%c", &option);
                           
                        }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);
                    
                         }
                         else
                         {
                               printf("Update Tool Cost?Y/N:");
                               do
                                 {
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",tool.cost);
                               }
                         }/*endelse*/
                      fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
               fwrite(&tool, sizeof(struct hardware),1, fp);
                        break;

                  }
            }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);//this line being executed
       }
            
            
  }/*endelse*/

      fclose(fp);
            
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18841917
Sorry, this :

     while (fread(&tool, sizeof(struct hardware), 1, fp) == sizeof(struct hardware))

should have been :

     while (fread(&tool, sizeof(struct hardware), 1, fp) == 1)

I mixed up the size and count parameters :)
0
 

Author Comment

by:sassy4sure
ID: 18841962
Ok, no error but nothing is happening after i enter a new quantity. when it should execute the next line

   if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);//stall here
                    
                        
                               printf("Update Tool Cost?Y/N:");
                               do
                                 {
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",tool.cost);
                               }
                         }
                      fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
               fwrite(&tool, sizeof(struct hardware),1, fp);
                        break;

                  }
            }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);//this line being executed
       }
      
            
  }/*endelse*/

      fclose(fp);
            
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18841977
>> Ok, no error but nothing is happening after i enter a new quantity. when it should execute the next line

What do you mean by "nothing is happening" ? Can you show the output of the program, including the values you gave as input ?
0
 

Author Comment

by:sassy4sure
ID: 18842022
Say i try to update record id  #2

{2, 0,79.50,"Lawn mower"}//displayed

I enter  y for update quantity

printf("Enter New Quantity:");
i enter 5
scanf("%d",tool.quantity);//stall here
I goes no further than that no matter how many times i press enter
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18842045
>> I goes no further than that no matter how many times i press enter

In the last complete function code you posted, you did this :

                 if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);
                   
                         }
                         else
                         {
                               printf("Update Tool Cost?Y/N:");
                               /* etc ... */
                         }/*endelse*/

So, after entering the quantity, the modification is written to the file and the function returns. Nothing else is written to the screen ...

Did you make any other modifications to the function ? If so, can you post the whole function again ?
0
 

Author Comment

by:sassy4sure
ID: 18842082
This is the complete function. Now I am getting the access violation error again after entering the new quantity
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
     int found = 0;
      while (fread(&tool, sizeof(struct hardware), 1, fp) == 1)
            {
          if(tool.toolId == toolnum)
                  {
              found = 1;
              printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
              printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                    printf("Update Tool Quantity?Y/N:");
                          do
                              {
                                scanf("%c", &option);
                           
                        }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                              
                              printf("Enter New Quantity:");
                                        scanf("%d",tool.quantity);
                         }
                         else
                         {
                        
                               printf("Update Tool Cost?Y/N:");
                               do
                                 {
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",&tool.cost);
                               }
                         }
                      fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
               fwrite(&tool, sizeof(struct hardware),1, fp);
                        break;

                  }
        }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);//this line being executed
       }
      
            
  }/*endelse*/

      fclose(fp);
            
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18842102
Change this line :

                                        scanf("%d",tool.quantity);

to this line :

                                        scanf("%d",&(tool.quantity));

scanf requires addresses to be passed as parametr !!!
0
 

Author Comment

by:sassy4sure
ID: 18842191
Srry thought i had that but its gone back to this:

Say i try to update record id  #2

{2, 0,79.50,"Lawn mower"}//displayed

I enter  y for update quantity

printf("Enter New Quantity:");
i enter 5
scanf("%d",tool.quantity);//stall here
I goes no further than that no matter how many times i press enter

so should the else be removed?
   if((option=='Y')||(option=='y'))
                         {
                               printf("Enter New Quantity:");
                               scanf("%d",tool.quantity);
                   
                         }
                         else//Possible cause of stall
                         {
                               printf("Update Tool Cost?Y/N:");
                               /* etc ... */
                         }/*endelse*/
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18842205
>> I goes no further than that no matter how many times i press enter

What do you mean by "stall". As I explained earlier, there is nothing happening after that line, the function returns !

If you want the option to change both quantity and cost, then you don't need the else, just do :

                    printf("Update Tool Quantity?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Quantity:");
                        scanf("%d",tool.quantity);
                    }
                    printf("Update Tool Cost?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Cost:");
                        scanf("%f",&tool.cost);
                    }
0
 

Author Comment

by:sassy4sure
ID: 18843118
Ok so it runs through now every thing seems fine I update the cost to 80.00 and the quantity to 5
for product 2 I exit the program I run the file update again and input product 2 to see if it is updated  the quantity and cost displayed are the same as before so the update did not replace the quantity or cost
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18843160
I tested the code myself, and it does update correctly for me ...

Is it possible that your program overwrites the modification somewhere else ?
0
 

Author Comment

by:sassy4sure
ID: 18843220
ok i see it,you've been patient though thanks a bundle :)
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18843260
>> ok i see it

Does that mean it's working now ?
0
 

Author Comment

by:sassy4sure
ID: 18843293
yes it works i was overwriting the file as u said, thank you.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18843303
Nice :)
0
 

Author Comment

by:sassy4sure
ID: 18844107
So I ran it a couple times and I fixed the overwriting problem it ran ok for while but now it is only finding record # 5
Note i made no changes to the original dat file when i try to update the cost fr record number 5 it stall again I made not changes to the function so i do not know where this problem is coming from.


void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
     int found = 0;
      while (fread(&tool, sizeof(struct hardware), 1, fp) == 1)
            {
          if(tool.toolId == toolnum)
                  {
              found = 1;
              printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
              printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                    printf("Update Tool Quantity?Y/N:");
                          do
                              {
                                scanf("%c", &option);
                           
                        }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                 if((option=='Y')||(option=='y'))
                         {
                             
                              printf("Enter New Quantity:");
                              scanf("%d",&(tool.quantity));
                         
                       
                               printf("Update Tool Cost?Y/N:");
                               do
                                 {
                                    scanf("%c", &option);
                           
                           }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));

                               if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",&(tool.cost));
                               }
                         }
                      fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
                     fwrite(&tool, sizeof(struct hardware),1, fp);
                        break;

                  }
        }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);
         }
     
           
  }/*endelse*/

      fclose(fp);
           
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18844897
I've tested the code over here several times, but didn't notice this behaviour - are you sure that nothing else was done to the file ? Does your program do anything else except call the update() function ? What was the input that you gave to the program ?
0
 

Author Comment

by:sassy4sure
ID: 18845052
The problem was i wasn't closing the file in another function.. You are right there is nothing wrong with it,silly me :) thanks again.
0
 

Author Comment

by:sassy4sure
ID: 18845077
But it still stalls here:
if((option=='Y')||(option=='y'))
                               {
                                     printf("Enter New Cost:");
                                     scanf("%f",&(tool.cost));//
                               }
I
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18845086
>> The problem was i wasn't closing the file in another function

Indeed. If you don't close the file, it might get corrupted when you open it again (unflushed buffers etc.).
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18845095
>> But it still stalls here:

Still the same reason as I said earlier. If you want to update both quantity and cost, then you have to use this code :

                    printf("Update Tool Quantity?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Quantity:");
                        scanf("%d",tool.quantity);
                    }
                    printf("Update Tool Cost?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Cost:");
                        scanf("%f",&tool.cost);
                    }

ie. : no else !!!
0
 

Author Comment

by:sassy4sure
ID: 18846060
I swear this is exactly as I have it no else and it refuses to go forward.
/*This Function updates the information in the cost and quantity field*/

void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
     int found = 0;
      while (fread(&tool, sizeof(struct hardware), 1, fp) == 1)
            {
          if(tool.toolId == toolnum)
                  {
              found = 1;
              printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
              printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                      printf("Update Tool Quantity?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Quantity:");
                        scanf("%d",&(tool.quantity));
                    }
                    printf("Update Tool Cost?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Cost:");
                        scanf("%f",&(tool.cost));
                    }
                      fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
                     fwrite(&tool, sizeof(struct hardware),1, fp);
                        break;

                  }
        }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);
         }
     
           
  }/*endelse*/

      fclose(fp);
           
}
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846118
>> and it refuses to go forward.

What do you mean ? You see this :

    Update Tool Cost?Y/N:

And you enter 'y', and this line is not shown :

    printf("Enter New Cost:");

Is that it ? That doesn't make any sense :)

Can you tell me exactly what output you get, and what input you give ?
0
 

Author Comment

by:sassy4sure
ID: 18846151
No, I see that line and I enter: 5

scanf("%f",&(tool.cost));//On this line it stalls and does not move forward after I press enter several times.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846170
That's the end of the function as I said earlier ... What happens after the function call ?
0
 

Author Comment

by:sassy4sure
ID: 18846268
Nothing, but shouldn't it return to the menu in main?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846282
Can you show your entire code please ?

And can you make sure that no other program has the data file open ?
0
 

Author Comment

by:sassy4sure
ID: 18846357

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZ 256


/*Data structure*/
struct hardware
          {
            int toolId;
            int quantity;
                  float cost;
                  char toolName[BUFSIZ];
      };

/*Function Prototypes*/
void transfer(FILE *,FILE *);
void update(void);
void addnew(void);
void delrec(void);
void display(void);
int getnum(const char *);
void findrec(FILE *,int );


int main()
{
    int option=0;
    FILE *in;
      FILE *out;
   
 
        in=fopen ("oldhardware.dat","rb");

        out=fopen ("newhardware.dat","wb");

       if(ferror(in) || ferror(out))
      {
        printf("File Error!!!\n");
            exit(EXIT_FAILURE);
      }

         else
         {
             
             
               do
               {
                     transfer(in,out);

        printf("Harware Store Inventory Checker\nPlease select a menu option\n");
            printf("1:\t Update Quantity\\Cost\n");
            printf("2:\t Add a New Record\n");
            printf("3:\t Delete a Record\n");
            printf("4:\t Display a Record\n");
            printf("5:\t Exit Program\n");
                  do
                {
                  scanf("%d",&option);
                }
            while( (option !=1)&&(option !=2)&&(option != 3)&&(option!=4)&&(option!=5) );

            switch (option)
            {
         case 1:update();
               break;

             case 2:
               break;

             case 3:
                  break;

             case 4:display();
                  break;

             case 5: return 0;
            }
        puts("Enter 5 to exit Or any other key to continue");
            option = getchar();

        
               }while (option != 5);
         }/*endelse*/

return 0;
}
/*This Function transfers the information in oldhardware.dat to newhardware.dat*/         
void transfer(FILE *infile,FILE *outfile)
{
      unsigned char buffer[BUFSIZ];
      size_t BytesRead;

                  
               while((BytesRead = fread(buffer, 1, sizeof buffer,infile)) > 0)
             {
               fwrite(buffer, 1, BytesRead, outfile);
             }
           if(ferror(infile) || ferror(outfile))
             {
             printf("File write Error!\n");
             }
               fclose(infile);
               fclose(outfile);
 
}
/*This Function updates the information in the cost and quantity field*/
void update(void)
{
  struct hardware tool;
  int toolnum;
  char option = '\0';
  FILE *fp;

  if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
else
      {


      printf("Enter the Record Number to update (1 - 50): ");
      scanf("%d", &toolnum);

       
     int found = 0;
      while (fread(&tool, sizeof(struct hardware), 1, fp) == 1)
            {
          if(tool.toolId == toolnum)
                  {
              found = 1;
              printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
              printf("\t\t%-7d%-19s%-8d%9.2f\n",tool.toolId, tool.toolName, tool.quantity,tool.cost);
                      printf("Update Tool Quantity?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Quantity:");
                        scanf("%d",&(tool.quantity));
                    }
                    printf("Update Tool Cost?Y/N:");
                    do {
                        scanf("%c", &option);
                    }while((option !='Y')&&(option !='y')&&(option !='N')&&(option!='n'));
                    if((option=='Y')||(option=='y')) {
                        printf("Enter New Cost:");
                        scanf("%f",&(tool.cost));
                     }
                     fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
                     fwrite(&tool, sizeof(struct hardware),1, fp);
                     break;
                  }
        }
       if (!found)
         {
            printf("\tTool Id #%d has no information.\n",toolnum);
         }
                 
  }/*endelse*/

      fclose(fp);
}
/*This function displays the information the the file by Record number*/
void display()
{
      struct hardware display;
      int found = 0;
      int id;
      FILE *fp;

if ( ( fp = fopen( "newhardware.dat", "r+b" ) ) == NULL ){
      printf( "File could not be opened.\n" );
  }
  else
   {
        printf("Enter the Tool ID#");
        scanf("%d",&id);
        while (fread(&display, sizeof(struct hardware), 1, fp) == 1)  
             {
          if(display.toolId == id)
                  {
              found = 1;
                    
                  printf("\t\t%-7s%-19s%-8s%9s\n", "Tool Id#", "Tool name", "Quantity","Cost");
                  printf("\t\t%-7d%-19s%-8d%9.2f\n",display.toolId, display.toolName, display.quantity,display.cost);
                }
            }
              if(!found)
               {
                  
                   printf("Tool Id# %d not found.",id);
               
               }      
      
     }
     fclose(fp);
  }
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846510
You open the file in your main(), and then open it again in the update() function without closing it first ... that's asking for problems.

I advise you to either close the file before opening it again, or to keep the file open, and use the same ...
0
 

Author Comment

by:sassy4sure
ID: 18846710
I chose to close it after I called transfer but I had already closed it here
               fclose(infile);
               fclose(outfile);
That didn't work either though.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846726
>> I chose to close it after I called transfer

transfer is in a loop. After calling update(), you come back to the beginning of the loop, and call transfer() again, but you closed the file !! You should only close the files if you don't need them any more. Alternativley, you have to re-open the file whenever you need to use it again.
0
 

Author Comment

by:sassy4sure
ID: 18846829
I really prefer not to pass anything to update but I need to transfer the file each time the program is run. why  doesn't changing it in transfer work the same?
0
 

Author Comment

by:sassy4sure
ID: 18846841
are you sure thats the problem is there is reason why scanf would stop taking input?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846862
>> I really prefer not to pass anything to update

Why ? Any specific reason ?



>> why  doesn't changing it in transfer work the same?

What do you mean ? If you close it in the transfer() function, then the files will still be closed the next time you call the transfer() function, which is in the next iteration of the do-while loop in main().

You should just follow the code of your program from beginning to end, and take note of every time you open, close write, read, etc. a file. You'll immediately see that there is a problem !
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18846869
>> are you sure thats the problem is there is reason why scanf would stop taking input?
It doesn't stop taking input ... it stops when you next call the transfer() function because the files have been closed.
0
 

Author Comment

by:sassy4sure
ID: 18846995
I see, I want transfer to execute every time the program is run but not every time I return to main is there anyother place I can sfely put it that won't interfere with the return to the menu?
I tried placing it here
 in=fopen ("oldhardware.dat","rb");

        out=fopen ("newhardware.dat","wb");

       if(ferror(in) || ferror(out))
      {
        printf("File Error!!!\n");
            exit(EXIT_FAILURE);
      }
            transfer(in,out);
before the loop but I am getting an  '*' : integral constant overflow error here:
fseek(fp, -1 * sizeof(struct hardware), SEEK_CUR);
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18847011
>> I tried placing it here ...

Make sure you remove the else-statement too then !!
0
 

Author Comment

by:sassy4sure
ID: 18847109
sigh... now it is stalling on quantity i think i going to call it quits tho
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 18847131
I think the problem is that you don't really understand what's happening with the files ... as I suggested earlier : go over the code, and try to follow what it does. Take note of everything that happens with the files (as if you were the compiler that had to do it), and you'll spot the problem.

What did you change in the main() ?
0
 

Author Comment

by:sassy4sure
ID: 18847212
I did that an I closed in main as u suggested
int main()
{
    int option=0;
    FILE *in;
      FILE *out;
   
 
        in=fopen ("oldhardware.dat","rb");

        out=fopen ("newhardware.dat","wb");

       if(ferror(in) || ferror(out))
      {
        printf("File Error!!!\n");
            exit(EXIT_FAILURE);
      }
            transfer(in,out);
            fclose(in);
            fclose(out);
        
             
             
               do
               {
                           


            printf("Harware Store Inventory Checker\nPlease select a menu option\n");
            printf("1:\t Update Quantity\\Cost\n");
            printf("2:\t Add a New Record\n");
            printf("3:\t Delete a Record\n");
            printf("4:\t Display a Record\n");
            printf("5:\t Exit Program\n");
                  do
                {
                  scanf("%d",&option);
                }
            while( (option !=1)&&(option !=2)&&(option != 3)&&(option!=4)&&(option!=5) );

            switch (option)
            {
         case 1:update();
               break;

             case 2:
               break;

             case 3:
                  break;

             case 4:
                  break;

             case 5: return 0;
            }
        puts("Enter 5 to exit Or any other key to continue");
            option = getchar();

        
               }while (option != 5);
        

return 0;
}
0
 

Author Comment

by:sassy4sure
ID: 18847483
So I stated a new project and it runs cleanly now with the above code :). I guess  you were right about closing the file, thankyou.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now