cplusplus.com example for reading text files表示可以使用getline
函数读取一行。但是,我不想得到一整行;我想只获得一定数量的角色。如何以保留字符编码的方式完成?
我需要一个像这样的函数:
ifstream fileStream;
fileStream.open("file.txt", ios::in);
resultStream << getstring(fileStream, 10); // read first 10 chars
file.ftell(10); // move to the next item
resultStream << getstring(fileStream, 10); // read 10 more chars
我考虑过读取char缓冲区,但这不会改变字符编码吗?
答案 0 :(得分:5)
我真的怀疑这里有关于“角色”这个词的混淆。从OP的问题来看,他使用术语“字符”来表示char
(而不是逻辑“字符”,如多字节UTF-8字符),因此用于从文本文件中读取术语“字符”可与“字节”互换。
如果是这种情况,您可以使用ifstream::read(),
从磁盘读取一定数量的字节,例如
ifstream fileStream;
fileStream.open("file.txt", ios::in);
char buffer[1024];
fileStream.read(buffer, sizeof(buffer));
读入char
缓冲区根本不会影响字符编码。存储在磁盘上的确切字节序列将被复制到缓冲区中。
但是,如果您使用的是多字节字符集,则每个字符都是可变长度的,这是另一回事。如果字符不是固定大小,则无法通过单个磁盘读取从磁盘读取完全 N个字符。这不是C ++的限制,这只是处理块设备(磁盘)的现实。在操作系统的最低级别,块设备按块进行寻址,而块又由字节组成。因此,您始终可以读取确切数量的字节从磁盘,但您无法从磁盘读取确切数量的逻辑字符,除非每个字符是固定的字节数。对于像UTF-8这样每个字符都是可变长度的字符集,你必须要读取整个文件,否则执行推测性读取并在每次读取后解析读取缓冲区以确定是否需要阅读更多文件。 / p>
答案 1 :(得分:2)
C ++本身没有字符编码的概念。 char
的大小始终与wchar_t
的大小相同。因此,如果您需要读取多字节字符集(例如utf-8)的X char
,那么您必须一次读取(单字节)char
(例如使用{ {1}} - 或X getchar()
s,推测性地,使用char
)并自行测试MBCS信号,或使用第三方库来执行此操作。
如果charset是固定宽度编码,并且你不介意在到达换行符时停止,那么istream::getline()
允许你指定要读取的最大字符数,可能就是你想。
答案 2 :(得分:1)
正如一些人所提到的,C / C ++标准库并没有真正提供任何基本上在字节级以上运行的东西。因此,如果您只想使用核心库,那么您就没有现成的选项。
要么检查您所选择的平台是否提供了另一个实现此功能的库,编写自己的解析器来处理字符编码,或者将诸如"c++ utf8 library"或"posix unicode"之类的内容打入Google并采取措施看看会发生什么。
可能有趣的点击:
我会给读者留下进一步的调查。
答案 3 :(得分:0)
我认为你可以使用与streambuf相关的流的sgetn成员函数...
char buf [32]; streamsize i = fileStream.rdbuf() - &gt; sgetn(&amp; buf [0],10);
将10个字符读入buf(如果有10个可读取),返回读取的字符数。