我用C实现自定义的词法分析器++,并试图在空白读取时,则ifstream的将无法读取出来。我被字符使用>>
读取字符,所有的空格不见了。有没有什么办法让ifstream的把所有的空格,并读出来给我吗?我知道,阅读整个字符串时,读取会在空白停下来,但我希望通过阅读人物的性格,我会避免这种行为。
尝试:.get()
,许多答案推荐,但它作为std::noskipws
同样的效果,那就是,我得到的所有的空间了,但不是新行字符,我需要一些法构造。
这里是有问题的代码(扩展注释截断)
while(input >> current) {
always_next_struct val = always_next_struct(next);
if (current == L' ' || current == L'\n' || current == L'\t' || current == L'\r') {
continue;
}
if (current == L'/') {
input >> current;
if (current == L'/') {
// explicitly empty while loop
while(input.get(current) && current != L'\n');
continue;
}
我打破了while
线和current
的每个值看上去它有和\r
或\n
绝对不是他们 - 中输入刚刚跳到输入文件的下一行。
有操纵禁用空格跳跃行为:
stream >> std::noskipws;
操作>>吃空格(空格,制表符,换行符)。使用yourstream.get()
读取每个字符。
编辑:
当心:平台(Windows,Un的X,苹果机)在换行符的编码不同。它可以是 '\ n', '\ r' 或两者兼而有之。这也取决于你如何打开文件流(文本或二进制)。
编辑(分析代码):
后
while(input.get(current) && current != L'\n');
continue;
会有\n
的current
,如果没有文件的末尾。之后,你继续while循环最外层。有下一行的第一个字符被读入current
。那是你不想要的吗?
我试图重现您的问题(使用char
和cin
代替wchar_t
和wifstream
):
//: get.cpp : compile, then run: get < get.cpp
#include <iostream>
int main()
{
char c;
while (std::cin.get(c))
{
if (c == '/')
{
char last = c;
if (std::cin.get(c) && c == '/')
{
// std::cout << "Read to EOL\n";
while(std::cin.get(c) && c != '\n'); // this comment will be skipped
// std::cout << "go to next line\n";
std::cin.putback(c);
continue;
}
else { std::cin.putback(c); c = last; }
}
std::cout << c;
}
return 0;
}
这一方案,适用于自身,消除其输出的所有C ++行注释。内while循环没有吃掉所有文本文件的末尾。请注意putback(c)
声明。如果没有换行不会出现。
如果它不能正常工作同样为wifstream
,这将是除了一个原因很奇怪:当打开文本文件没有保存为16bit的焦炭,焦炭\n
在错误的字节结束了......
包裹在一个std::streambuf_iterator
流(或它的缓冲器,具体而言)?这应该忽略所有的格式,也给你一个很好的Iterator接口。
另外,一个更高效,防呆,方法可能只使用Win32 API(或升压)的文件内存映射。然后,你可以使用普通的指针穿越它,你保证什么都不会被跳过或运行时转换。
流提取具有相同的行为,并跳过空白。
如果你想读的每一个字节,可以使用未格式化的输入功能,如stream.get(c)
。
为什么不干脆用getline
?
你会得到所有的空格,而你不会得到的行结束字符,你还是会知道它们就躺在那里:)
你可以以二进制方式打开流:
std::wifstream stream(filename, std::ios::binary);
你会失去,如果你做任何格式化操作提供我流。
另一种选择是读取整个流成一个字符串,然后处理字符串:
std::wostringstream ss;
ss << filestream.rdbuf();
当然,从ostringstream获取字符串rquires字符串的额外拷贝,所以你可以考虑在某个时候改变这一点,如果你喜欢冒险使用自定义流。编辑:别人提istreambuf_iterator,这可能是做这件事比读全码流转换为字符串的更好的方法。
你可以只包裹流中的std :: streambuf_iterator让所有的空格和换行这样的数据。
/*Open the stream in default mode.*/
std::ifstream myfile("myfile.txt");
if(myfile.good()) {
/*Read data using streambuffer iterators.*/
vector<char> buf((std::istreambuf_iterator<char>(myfile)), (std::istreambuf_iterator<char>()));
/*str_buf holds all the data including whitespaces and newline .*/
string str_buf(buf.begin(),buf.end());
myfile.close();
}
只需使用函数getline。
while (getline(input,current))
{
cout<<current<<"\n";
}
我结束了刚刚开放破解Windows的API,并用它首先读取整个文件到缓冲区中,然后通过字符读取缓冲字符。多谢你们。