如果流读取的字符与文件中写入的字符不同

问题描述 投票:0回答:1

我正在将寄存器作为char数组记录到文件中。当我将其写入文件时,它会成功写入。我打开文件并找到我想要的字符,除了记事本显然将Unicode字符0000(NULL)显示为空格。

例如,条目

id = 1000; //an 8-byte long long
name = "stack"; //variable size
surname = "overflow"; //variable size
degree = "internet"; //variable size
sex = 'c'; //1-byte char
birthdate = 256; //4-byte int

在文件上成为此名称:

&      èstackoverflowinternetc   

或,将在此处放在方括号之间时消失的unicode字符数:

&[3]|      [1]è|stack|overflow|internet|c|  [1] | //separating each section with a | for easier reading. Some unicode characters disappear when I post them here, but I assure you they are the correct ones
SIZE|    ID    | name| surname| degree |g| birth

(书写正常,并放置了预期的字符)

麻烦的是,当下面代码中的控制台打印缓冲区正在从文件读取的内容时,它给了我下面的记录(包括多余的空格)

         Þstackoverflowinternetc   

哪个不好,因为它会给我返回错误的ID和生日。 “ -21”和“ 4747968”或“Ù”和“ -1066252288”。其他字段不受影响。很奇怪,因为大小字节在控制台中显示为空白,因此它不能拆分名称,姓氏,程度和性别。

ifstream infile("alumni.freire", ios::binary);
if(infile.is_open()){
    infile.seekg(pos, ios::beg);
    int size;
    size = infile.get();
    char charreg[size];
    charreg[0] = size;

    //testing what buffer gives me
    for(int i = 1; i < size; i++){
        charreg[i] = infile.get();
        cout << charreg[i];
    }
}

我在做什么错?

编辑:为更好地解释我做了什么:我从用户输入中获取第一个“代码”上的条目,并在创建我实现的“ reg”类时将它们用作参数。然后,reg类进行(足够地,我已经测试过)到字符串的转换,并计算一个包含实例大小,名称大小,姓氏大小和程度大小的隐藏的四元素char数组。程序在文件上写入类时,它就被完美地编写了,正如我在第二个“代码”部分中所示。 (例如,如果进行计算,您将看到'&'等于整个事物的大小)。当我从文件中读取文件时,由于某种原因,它在控制台上的显示方式有所不同。不同的字符。但它会读取正确数量的字符,因为“名称”,“姓氏”和“度”正确显示。

c++ file fstream ifstream
1个回答
0
投票

按原样编写您的结构的想法很好。但是您的方法是错误的。

您必须有一些分隔字段的内容。例如,您知道您的ID长8字节,太棒了!您可以读取8个字节:

long long id;
read(fd, &id, 8);

在您的示例中,您得到-24是因为您读取了完整ID号的第一个字节。

但是对于文件的其余部分,您怎么知道名字和姓氏的长度?您可以逐字节读取,直到找到空字节为止。

但是我建议您使用结构更清晰的文件。例如,您可以定义如下结构:

long long id;        // 8 bytes
char firstname[256]; // 256 bytes
char lastname[256];  // 256 bytes
char sex;            // 1 byte
int  birthdate;      // 4 bytes

通过这种结构,您可以轻松地超级读写:

struct my_struct s; 
read(fd, &s, sizeof(struct my_struct)); // read 8+256+256+1+4 bytes
s.birthdate = 128;
write(fd, &s, sizeof(struct my_struct));// write the structure

当然,您会松开名字和姓氏的“可变长度”。一个名称真的需要超过100个字符吗?

在您确实需要的情况下,可以在每个可变长度值上引入标头。但是您失去了一次读取所有内容的能力。

long long id;
int foo_size;
char *foo;

然后阅读:

struct my_struct s;
read(fd, &s, 12); // read the header, 8 + 4 bytes
char foo[s.foo_size];
read(fd, &s, s.foo_size);

您应定义确切需要保存的内容。定义一个精确的数据结构,您可以在读取时轻松推断出它,避免使用诸如“哦,让我们读取直到空字节”之类的内容。

我用C函数来解释你,因为它更具代表性。您知道所读和所写。开始玩这个游戏,然后尝试使用c ++ stream / function进行同样的操作

© www.soinside.com 2019 - 2024. All rights reserved.