0

我是论坛的新手。我有一个奇怪的问题。我有一个简单的代码,它使用 read() 函数从文件中读取未格式化的数据。代码如下。

int main () {
    ifstream meshfile;
    char buf[1000], ch;
    memset(buf, 0, 1000);
    meshfile.open ("sometextfile");
    meshfile.read (buf, 1000);//38+62+(19*47) + 7);
    cout << strlen(buf) << std::endl;
    cout << buf << std::endl;
}

使用下面的示例输入文件运行代码时,会给出 1006 作为 buf 的长度,并为 buf 打印额外的字符。奇怪的是,这只发生在 bufsize 为 1000 & 1000 个字符被读取时。将 bufsize 更改为 > 1000 并读取 1000 个字符不会产生此错误。这可能是编码问题吗?

示例输入文件是

fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsjgvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg

4

4 回答 4

1

你的问题是使用strlen 它期望一个以\0.

read不在\0缓冲区末尾添加 a ,因此 strlen 读取超出缓冲区的边缘。

于 2012-11-06T08:06:27.903 回答
0

使缓冲区长度为 1001 个字符,为 nul 终止留出空间。Memset 1001 也是。没有那个 nul 终止符, strlen 将无法工作。

更好的是,使用 <array> 而不要使用 memset。一个简单的 buf[1000] = 0 就可以了。

于 2012-11-06T08:04:53.200 回答
0

从文件中读取的不是以 '\0' 结尾的字符串,而是原始数据。您应该检查包含实际读入缓冲区的字节数的 stream.gcount() 的返回值,并在后续代码中使用它。手册在这里

  size_t size = meshfile.read(buf, sizeof(buf)/sizeof(*buf)).gcount();
  std::cout << size << std::endl;
于 2012-11-06T08:06:12.000 回答
0

我认为这里的人,我的意思是:

1)read(..) 不添加空终止符。

2)您使用 memset 将缓冲区初始化为 0。当您读取 < 1000 个字符时,读入的最后一个字符之后的数组元素仍然为 0(实际上为 null,因为它们已初始化为该值)因此即使 read(..) 没有添加 null 终止符,事情没有打破。这就是为什么 Jive Dadson 要求您将缓冲区大小调整为 1001 个字符并将您的数组初始化为 0,这样即使您读入 1000 个字符,第 1001 个字符仍然是 0,并将充当空终止符。

但这实际上是一个错误。考虑一下当你读到最后一行 < BUF_SIZE 时会发生什么?因此,最好按照一些海报的建议检查每轮读入的字符数。

3)当您读取 > 1000 个字符时,您是否更改为更大的缓冲区,并且您是否为这个更大的缓冲区将缓冲区初始化为“0”?如果是这样,自然不会有问题,因为情况与上述相同。如果没有,我很好奇您如何将 > 1000 个字符读入 1000 个字符的缓冲区。

4)基本上您当前读取数据的方法是不可靠的。您应该调整缓冲区的大小,使其比您打算读取的最大值多 1 个元素。每次读取后,如果您打算将 buf 作为字符串传递并执行复制、printf 等操作,则应获取实际读入的字符数并设置空终止符。

于 2012-11-06T09:12:32.260 回答