我有以下代码,我试图读取文件的内容并显示它,并写入另一个文件。我的问题是我在屏幕上看到的内容与文件的内容完全不同。我已经放置了部分文件内容和部分结果显示
#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);
}
源文件的部分内容:
0,43
43,95
138,159
297,279
576,153
729,64
显示结果的前几行:
3474018176930688048,13879
3472896773804077344,14136
4049914982932231728,13362
3978707281317738034,12342
3474306356368193848,14132
3688511012684903220,14130
724298015681099573,13624
源文件和目标文件具有完全相同的副本
答案 0 :(得分:2)
您的文件不包含结构,它包含以逗号分隔的值(数据的文本表示)。
结构以二进制形式存储,而不是以文本形式存储。
当您阅读时,您的程序会尝试将其读取的内容解释为二进制文件。撤消:
$ printf "%x%x" 3474018176930688048 13879 | sed 's/../\\\\x&/g' | sed 's/^/echo -e /e'
061 34,067
要读取以文本形式存储的数据,您可以使用fgets
读取每一行,然后解析它(例如:使用sscanf()
)。
答案 1 :(得分:1)
写一个指向文件的指针是没有意义的。读回该指针的代码与编写它的代码不具有相同的内存视图。所以不要这样做。
相反,在开始编写代码以读取和写入二进制文件之前,请退一步。二进制文件是字节流。因此,在文件中定义所需的字节流。然后编写代码来编写您定义的确切字节流。然后编写代码以读入具有您定义的确切字节流的文件。
然后,如果你有问题,你会知道应该责备什么。检查文件中的字节并确保它们符合定义。如果没有,这是作家的错。如果是这样,这是读者的错。
答案 2 :(得分:1)
这是一些工作代码。我离开了写作部分,因为我不知道你正在寻找什么样的输出。只需阅读阅读逻辑,你就会知道如何修复写作部分。
我将调试printf留在那里,以便您可以了解代码的工作方式以及如何解析csv文件以获得您正在寻找的结果。如上所述,文件是文本(csv)文件而不是二进制文件。您尝试阅读它的方式是读取二进制文件。所以这种方法不会有所帮助。现在要读取二进制文件,你必须将它们存储为二进制文件。
#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;
}
答案 3 :(得分:0)
你也应该打开文件来写二进制文件:
FILE *wrt=fopen("abc2.doc","w+b"); //instead of "w+"