C++ Ifstream从文本文件中读取错误字符
我有以下简单代码,将文本文件的内容读入字符数组:C++ Ifstream从文本文件中读取错误字符,c++,io,C++,Io,我有以下简单代码,将文本文件的内容读入字符数组: const char* name = "test.txt"; std::cout << "Loading file " << name << std::endl; std::ifstream file; file.open(name); file.seekg (0, std::ios::end); int length = file.tellg(); std::cout << "Size: " &l
const char* name = "test.txt";
std::cout << "Loading file " << name << std::endl;
std::ifstream file;
file.open(name);
file.seekg (0, std::ios::end);
int length = file.tellg();
std::cout << "Size: " << length << " bytes" << std::endl;
file.seekg (0, std::ios::beg);
char* buffer = new char[length];
file.read(buffer,length);
file.close();
std::cout.write(buffer,length);
const char*name=“test.txt”;
std::cout阅读有关打开文件以进行二进制读取的信息(谷歌或请参阅)。您可能希望以二进制模式打开文件:
file.open(name, ios_base::in | ios_base::binary);
否则,标准库会为您将每个Windows换行符(CR+LF)转换为单个\n
这意味着您可以从文件中读取的字符数与文件大小不同。调用read()
时,它会读取尽可能多的字符。如果它不能读取您请求的字符数,它将设置流的故障位您开始使用一些非常错误(但普遍存在)的观点。
file.tellg()
不返回int
;它返回一个实现
类型为streampos
的已定义对象,该对象必须是类类型,并且可以
或者可能无法转换为整体类型。如果是的话
可转换为整数类型(我不知道有什么实现
如果没有,即使不是必需的),也不能保证
得到的整数表示的不仅仅是一个神奇的cookie,它
将允许重新搜索到相同的位置
实际上,这在现代机器上可能不是什么大问题:两者都有
Unix和Windows返回文件开头的偏移量(以字节为单位)。
在Unix的情况下,这很好,因为
内部表示与外部表示是一对一的。在这种情况下
对于Windows,有一个行结尾的重新映射:在文本文件中,一行
结尾是一个两字节的0x0D,0x0A序列,读取时变成,
单个字符'\n'
。和streampos
(转换为整型)
以字节为单位给出必须在文件中查找的位置的偏移量,而不是
要到达该位置必须读取的字符数。为了东西
就像你看起来在做的一样,这不是问题;分配的
缓冲区可能比需要的大一点,但它永远不会太大
小的
请注意,在大型机上可能不是这样。历史上,在
至少,大型机使用面向块的文件,并且
streampos
可以很容易地分解为字段,并使用
用于块编号的特定位数,以及用于字节的其他位数
块中的偏移量。取决于这些在世界上的布局,
像您这样分配的缓冲区很容易达到几个数量级
太大,或者如果偏移量放在高阶位上,则太小
获得所需缓冲区确切大小的唯一可靠方法是
取决于系统,在某些系统(包括Windows)上,可能存在
除了读取所有字符并计数外,没有其他方法
(要求streampos
为类类型的原因是,
历史上,许多旧的多字节编码都有一个编码状态;您
在不知道字符的情况下无法正确解码字符
因此,要求streampos
包含两个不同的
信息:要在文件中查找的位置,以及有关
这个状态。我不认为有任何依赖于状态的多字节
不过,现在广泛使用的编码。)也许您可以使用readsome
函数,在Windows上查看您实际读取了多少。不一定在其他系统上。