0

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

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 是这样填充的:Hello world!@T#^@$@FF(垃圾)

该文件没有任何内容,只有上面的内容。

平台:Win 7,VS 2012

任何想法如何解决这个问题。(解决了)

(问题 2)现在我面临另一个问题, fle.read 有时读取的大小超过了我给出的大小。例如,如果我像 fle.read(buffer, 1000) 一样通过,它在某些情况下会结束 (strlen(buffer) = 1500。我该如何解决这个问题?

问候,

4

7 回答 7

5

C 中的 char[]-strings 通常以 null 结尾。它们比必要的长一个字节,最后一个字节设置为0x00。这是必要的,因为 C 无法判断数组的长度。

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

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

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

于 2013-10-08T12:21:55.450 回答
3

我认为您的问题不在于您的数组包含垃圾,而是您忘记将空终止符放在末尾,并且您的 print 语句不知道何时停止。

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

尝试这个:

ary = new char[count+1];
fle.read(ary, count);
ary[count] = '\0';
于 2013-10-08T12:22:08.280 回答
2

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

于 2013-10-08T12:37:41.030 回答
2

好吧,最明显的问题是您正在分配 using 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]。正确地做到这一点非常困难。(例如,它需要一个 try 块和一个 catch。)

于 2013-10-08T13:18:32.620 回答
1

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

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

如果你只打印count字符,那么你就不会溢出。如果您对数组进行了空终止,您也不会忘记为空终止符分配一个额外的字符。

而不是使用原始数组 and new,将缓冲区读入std::string. 您应该尽量避免使用以 null 结尾的字符串。在与非 C++ 库执行互操作时使用它们。

于 2013-10-08T12:21:22.993 回答
0

尝试这个

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

缺少终止的空字符 - 它不在文件中,您必须在之后添加它

于 2013-10-08T12:23:47.453 回答
0

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

ary = new char[count + 1];
ary[count] = '\0';
于 2013-10-08T12:25:14.887 回答