将字节从文件读取到数组变量C ++

时间:2011-03-10 14:53:15

标签: c++

这是我对this question

的跟进问题

当我尝试这个时:

int main ( void ) {
fstream F ( soubor1, ios::out | ios::binary );
unsigned int x = 0xc4;
F.write ( ( char * ) &x, 1 );
x = 0x8d;
F.write ( ( char * ) &x, 1 );
F.close();
F . open ( soubor1, ios::in | ios::binary );
while ( F. read ( (char * ) & x, 1) )
cout << x << " ";
return 0;}

它的工作方式我认为它会起作用...... 但是当我这样做时:

int main ( void ) {
    fstream F ( soubor1, ios::out | ios::binary );
    unsigned int x = 0xc4;
    F.write ( ( char * ) &x, 1 );
    x = 0x8d;
    F.write ( ( char * ) &x, 1 );
    F.close();
    F . open ( soubor1, ios::in | ios::binary );
    unsigned int a[2]; //or unsigned int * a = new unsigned int[2];
    while ( F. read ( (char * ) & a[0], 1) )
    cout << a[0] << " ";
    return 0;}

..所以它不打印“196 141”...但是有些疯狂的数字...

提前致谢,

NikolasJíša

3 个答案:

答案 0 :(得分:2)

在读取之前未初始化

a[0],因此值为垃圾。然后,您在char的第一个字节中读取a[0],以便获得正确的值,但其余部分则没有。

你应该使用char而不是int,因为int通常更大(它们的大小通常是{{1}的4倍或8倍1}},在现代平台上。)

与您的想法相反,在char之前将a[0]设置为0也不会有任何帮助,至少不会因为endianness问题而无法移植。< / p>

答案 1 :(得分:1)

这是因为sizeof(char) == 1sizeof(int) == 4std::ostream::write(const char*, size_t)函数将其最后一个参数解释为要写入的字节数。所以当你写的时候,你只写2个字节。 std::istream::read(char*, size_t)函数还将其最后一个参数解释为要读取的字节数。

因此,使用一些图表来表示代码,我们有:

fstream F ( soubor1, ios::out | ios::binary );
unsigned int x = 0xc4;

// x =
// ,---------------------------.
// | 0xc4 | 0x00 | 0x00 | 0x00 |
// `---------------------------'

F.write((const char*)&x, 1);

// This write the first byte of x into the file,
// that is it write the byte 0xc4

x = 0x8d;


// x =
// ,---------------------------.
// | 0x8d | 0x00 | 0x00 | 0x00 |
// `---------------------------'

F.write((const char*)&x, 1);

// This write the first byte of x into the file,
// that is it write the byte 0x8d

F.close();
F.open( soubor1, ios::in | ios::binary );

unsigned int a[2];

// a =
// ,-------------------------------------------------------.
// |  ??  |  ??  |  ??  |  ??  |  ??  |  ??  |  ??  |  ??  |
// `-------------------------------------------------------'

F.read((char*)&a[0], 2);

// a =
// ,-------------------------------------------------------.
// | 0xc4 | 0x8d |  ??  |  ??  |  ??  |  ??  |  ??  |  ??  |
// `-------------------------------------------------------'

// You just read two bytes, while a point to a region that is
// 8 bytes long. So only the first two bytes of the first int
// are initialized, all the other value are undefined.

您可以通过以下方式更正代码:

int main () {
    fstream F ( soubor1, ios::out | ios::binary );
    unsigned int x = 0xc4;
    F.write ( ( char * ) &x, sizeof(unsigned int) );
    x = 0x8d;
    F.write ( ( char * ) &x, sizeof(unsigned int) );
    F.close();
    F.open ( soubor1, ios::in | ios::binary );
    unsigned a[2];
    F.read((char*)a, 2 * sizeof(unsigned int));
    for (size_t i = 0; i < 2; ++ i)
        cout << a[i] << " ";
    return 0;
}

答案 2 :(得分:0)

您正在读取int s的数组,其中(可能)长度为4个字节。

read调用只读取一个字节,这是数组中第一个int的4个字节中的第一个字节。由于数组没有首先初始化,所以当你执行cout << a[0]时会发生一个int,它的值是由刚读过的一个字节和已经存在的其他3个字节产生的。显然,这不会产生您期望的值。

您应该将unsigned int a[2]更改为unsigned char a[2],然后才能生效。