【发布时间】:2010-12-12 16:09:59
【问题描述】:
这些是我无法改变的:
- 语言是 C++
- 但是,文件是用旧的
fopen()打开的 - 文件未以二进制模式打开
这是我必须做的:
- 编写一个将整个文件加载到
std::string中的函数。行只能由\n分隔,而不是其他变体。
这就是我所做的:
string ReadWhole()
{
Seek(0);
char *data = new char[GetSize()];
if (1 != fread(data, GetSize(), 1, mFile))
FATAL(Text::Format("Read error: {0}", strerror(errno)));
string ret(data, GetSize());
delete[] data;
return ret;
}
作为参考,这是GetSize,但它只是返回文件的大小(缓存):
int GetSize()
{
if (mFileSize)
return mFileSize;
const int current_position = ftell(mFile);
fseek(mFile, 0, SEEK_END);
mFileSize = ftell(mFile);
fseek(mFile, current_position, SEEK_SET);
return mFileSize;
}
这就是问题
fread() 失败,因为文件有 \r\n 行结尾,它们只计为 1 个字符而不是 2 个字符,因此它尝试读取的字符数超过文件中的字符数。
我可以用fgets 修复它,但我想知道是否有更好的方法。谢谢。
【问题讨论】:
-
第一个问题很好。欢迎来到 SO!
-
C 中没有
std::string。标签已删除。 -
看来您正在将 mFileSize 初始化为零,并使用它来指示该值尚未被缓存。但是,由于零是有效的文件大小,您应该使用不同的标记值,例如 -1。
-
请注意,您的代码中存在潜在的内存泄漏。如果
string ret(...);抛出std::bad_alloc,您将泄漏data中的缓冲区。