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

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

Answers


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;
}

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()).


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.


Need Your Help

How do you change the program team explorer uses for comparisons?

version-control team-explorer difftool visual-studio-team-system

I would like to have team explorer use BeyondCompare or SourceGear's diffmerge in order to do my conflict resolution in team explorer. I know its possible, but where is the setting for that and wha...

Display flashdata with codeigniter and flexiauth

php codeigniter

I am trying to display a (flash) message when a user tries to access a page where he does not have the privileges for.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.