文件末尾的C ++垃圾

时间:2013-10-08 12:16:10

标签: c++

我有一个问题,我不知道如何解决它。 问题是:

char * ary = new Char[];

ifstream fle;
fle.open(1.txt, ios_base::binary);
fle.seekg(fle.end);
long count = fle.tellg();
fle.seek(fle.beg);

这是问题所在: 文件1.txt包含:Hello world!。

执行时:

ary = new char(count);
fle.read(ary, count);
像这样填充的ary:你好世界! @T#^ @ $ @ FF(垃圾)

该文件只是在上面的内容中没有任何内容。

平台:赢7,VS 2012

知道如何解决这个问题。 (解决)

(问题2) 现在我面临另一个问题,fle.read有时阅读超过我给出的尺寸。例如,如果我像fle.read(缓冲区,1000)一样传递,它在某些情况下结束(strlen(缓冲区)= 1500.我该如何解决这个问题?

此致

7 个答案:

答案 0 :(得分:5)

char [] - C中的字符串通常以空值终止。它们比必要长一个字节,最后一个字节设置为0x00。这是必要的,因为C无法分辨数组的长度。

从文件中读取二进制数据时,不会在字符串中读取终止空字符。这意味着像printf这样的函数在未知长度的char数组上运行,它将输出数组以及恰好在内存中出现的任何数据,直到它遇到空字符。

解决方案:将char [] - 缓冲区分配比数据长度长一个字节,并手动将最后一个字节设置为0

更好的解决方案:不要使用C风格的char数组。这是面向对象的方式,并使用类std::string来表示字符串。

答案 1 :(得分:3)

我认为您的问题并不是您的数组包含垃圾,而是您忘记将null-terminator字符放在最后,而print语句不知道何时停止。

另外,您写了new char(count)而不是new char[count]。在第一种情况下,您只实例化一个charcount,而在第二种情况下,您创建一个count个字符的缓冲区。

试试这个:

ary = new char[count+1];
fle.read(ary, count);
ary[count] = '\0';

答案 2 :(得分:2)

其他大多数答案都错过了一个非常重要的观点: 当您执行ary = new char(count);时,您将使用ASCII代码count的符号分配初始化的单个字符。 你应该这样写:ary = new char[count + 1];

答案 3 :(得分:2)

嗯,最明显的问题是你正在分配使用 new char(count),分配了一个char,已初始化 与count。您可能尝试做的是new char[count]。你真正需要的是:

std::vector<char> arr( count );
fle.read( &arr[0], count );

或者在分配中可能count + 1,如果你想要跟踪 缓冲区中的'\0'

编辑:

由于您仍然遇到问题:fle.read永远不会阅读 超过要求。 fle.gcount()之后返回什么 读?

如果你这样做:

std::vector<char> arr( count );
fle.read( &arr[0], count );
arr.resize( fle.gcount() );

你应该有一个正好具有char个数的向量 你看过了。如果你想将它们作为一个字符串,你可以构造 一个来自arr.begin(), arr.end(),甚至使用std::string 而不是std::vector<char>开头。

如果你需要一个'\0'终止字符串(用于接口) 传统软件),然后创建一个大小为的向量 count + 1代替count,而&arr[0]将是您的。'\0' new char[count]字符串。

尝试在此处使用{{1}}。这非常困难 这样做是正确的。 (例如,它需要一个try块 并抓住了。)

答案 4 :(得分:1)

我们必须在这里猜一点,但很可能这归结为调试问题。缓冲区已正确填充,但您检查的内容不正确。

现在,ary被声明为char*,我怀疑当您尝试检查ary的内容时,您使用了一些需要以空终止数组的打印方法。但是你没有空终止数组。所以你有一个缓冲区溢出。

如果您只打印了count个字符,那么您就不会超支。如果您使用null终止数组,也不会忘记为null终止符分配额外的字符,那么你也不会。

而不是使用原始数组和new,将缓冲区读入std::string会更有意义。您应该尝试尽可能避免以null结尾的字符串。在使用非C ++库执行互操作时使用它们。

答案 5 :(得分:0)

试试这个

ary = new char[count + 1];
fle.read(ary,count);
ary[count] = '\0';

终止空字符丢失 - 它不在文件中,之后你必须添加它

答案 6 :(得分:0)

您正在读取文件的count个字符,您必须分配一个额外的字符来提供字符串终结符(\0)。

ary = new char[count + 1];
ary[count] = '\0';