how to read contents of a structure using fread() in c

牧云@^-^@ 提交于 2019-12-01 12:42:34

问题


I have the following code where I am trying to read the content of a file and display it and also write to another file. My problem is the content i get on the screen is completely different from the content of the file. I have put parts of the contents of the file and parts of the result displayed

#include<iostream>
#include <stdint.h>
#include <stdio.h>
struct test
{
uint64_t start;
uint16_t length;
struct test *next;   
};

void main()
{
    char frd[32];
        std::cout<<"\nEnter name of file to read?\n";
    std::cin>>frd;
    FILE *rd=fopen(frd,"r+b");
    FILE *wrt=fopen("abc2.doc","w+");
     struct test test_st;

    while(fread (&test_st, sizeof(test_st), 1, rd))
{
       fwrite (&test_st,sizeof(test_st),1,wrt);
    printf("%llu,%u\n", test_st.start, test_st.length);
 }
fclose(rd);
fclose(wrt);
}

Partial content of the source file:

0,43 
43,95 
138,159
297,279
576,153
729,64

First few lines of the result displayed:

3474018176930688048,13879
3472896773804077344,14136
4049914982932231728,13362
3978707281317738034,12342
3474306356368193848,14132
3688511012684903220,14130
724298015681099573,13624

The source and destination files have exact copies


回答1:


Here is the some working code. I left the writing part as I dont know what kind of output you are looking for. Just go through the reading logic and you ll have an idea how to fix the writing part.

I left the debug printf there so that you can understand how the code is working and how the csv files is being parsed to get the results you are looking for. As mentioned above the file is a text(csv) file not a binary file. The way you are trying to read it is meant to read binary files. So that approach wont going to help. Now to read binary files you have to store them as binary.

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

struct test {
  uint64_t start;
  uint16_t length;
  struct test *next;   
};

int main(void)
{
  char frd[32];
  std::cout<<"\nEnter name of file to read?\n";
  std::cin>>frd;
  FILE *rd=fopen(frd,"r+b");
  FILE *wrt=fopen("abc2.doc","w+");
  struct test test_st;
  char readLine[100];

  while(fgets(readLine, 100, rd) != NULL) {
    // Removing the new line from the end
    // This is a quick hack as Windows have two characters
    // to represent new line. It is not needed to remove newline.
    // I did so that printf output look pleasing
    readLine[strlen(readLine) - 1] = '\0';
    printf("\nr=%s", readLine);

    // Splitting the string based on ','
    // and then converting it to number
    char *token = NULL;
    token = strtok(readLine, ",");
    test_st.start = atol(token);
    printf("\nt1=%s, test_st.start=%llu", token, test_st.start);

    token = strtok(NULL, ",");
    test_st.length = atoi(token);
    printf("\nt2=%s,test_st.length=%d", token, test_st.length);
    //fwrite (&test_st,sizeof(test_st),1,wrt);
    //printf("%llu,%u\n", test_st.start, test_st.length);
  }
  fclose(rd);
  fclose(wrt);
  return 0;
}



回答2:


Your file does not contain a structure, it contains comma-separated values (a textual representation of data).

A structure is stored in binary form, not in text form.

When you read, your program tries to interpret what it reads as binary. Undoing that:

$ printf "%x%x" 3474018176930688048 13879 | sed 's/../\\\\x&/g' | sed 's/^/echo -e /e'
061 34,067

To read data stored in textual form, you can read each line with fgets, and then parse it (e.g: using sscanf()).




回答3:


It makes no sense to write a pointer to a file. The code that reads back that pointer won't have the same view of memory as the code that wrote it. So don't do that.

Instead, before you start writing code to read and write to and from binary files, step back for a second. A binary file is a stream of bytes. So define the stream of bytes you want in the file. Then write code to write the exact stream of bytes you defined. Then write code to read in a file that has the exact stream of bytes you defined.

Then, if you have a problem, you will know what to blame. Check the bytes in the file and make sure they comply with the definition. If not, it's the writer's fault. If so, it's the reader's fault.




回答4:


You should open the file for writing binary as well:

FILE *wrt=fopen("abc2.doc","w+b"); //instead of "w+"


来源:https://stackoverflow.com/questions/8333074/how-to-read-contents-of-a-structure-using-fread-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!