ifstream read()的奇怪问题

时间:2012-11-06 08:01:54

标签: c++

我是论坛的新手。我有一个奇怪的问题。我有一个简单的代码,使用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&amp;读取1000个字符。将bufsize更改为&gt; 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 gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg   fdjgjdskgggggggggggggggggggggggggggggj bvjgdsv dsjkvgds gvdsj gvjdsgvjksdjkfgdsjkgfdsjgfsdjgfjkdsgfkjsdgjfgsdjfgdsjgfsdjgfjsdgfjsgfjsdgfjgsdjfgsdjfgdsjgfsdjgfsdjgfjsdgfjsdgfjsdg

4 个答案:

答案 0 :(得分:1)

你的问题是使用strlen 它期望一个字符串以\0终止。

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

答案 1 :(得分:0)

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

更好的是,使用&lt; array&gt;并且不要使用memset。一个简单的buf [1000] = 0就可以了。

答案 2 :(得分:0)

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

  size_t size = meshfile.read(buf, sizeof(buf)/sizeof(*buf)).gcount();
  std::cout << size << std::endl;

答案 3 :(得分:0)

我认为这里和我的意思是:

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

2)使用memset将缓冲区初始化为0。当你阅读&lt; 1000个字符,读入最后一个字符后的数组元素都是0(实际上是null,因为它们被初始化为该值)因此即使read(..)没有添加空终止符,事情也没有破坏。这就是为什么Jive Dadson要求你将缓冲区的大小调整为1001 char并将数组初始化为0,这样即使你读了1000个字符,第1001个字符仍然是0并将作为空终止符。

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

3)当你阅读&gt; 1000个字符,您是否更改为更大的缓冲区,并为此更大的缓冲区初始化缓冲区为“0”?如果是这样,你就不会有问题,因为情况与上述相同。如果没有,我很好奇你如何阅读&gt;将1000个字符放入1000个字符缓冲区中。

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