我正在尝试从文件中读取。我使用的代码是
ifstream is;char c;
is.open("text.txt");
while(is.good() && !isdigit(is.peek()))
{ is.get(c)
word+=c;
}
问题是最后一个字符被读取了两次(为什么?)例如,如果文件中的单词是粉红色的,则单词的值在循环后变为 pinkk 请提出解决方案
在尝试阅读后,您总是想检查输入是否成功。当流不知道要读取哪种值时,您首先检查。如果您想使用peek()
,您可能应该先进行测试std::char_traits<char>::eof()
,例如:
for (std::char_traits<char>::int_type c;
std::char_traits<char>::eof() != (c = in.peek())
&& !std::isdigit(static_cast<unsigned char>(c); ) {
...
}
在您的设置中,我个人会使用std::istreambuf_iterator<char>
它,因为它更容易,实际上:
for (std::istreambuf_iterator<char> it(in), end;
it != end && !std::isdigit(static_cast<unsigned char>(*it); ++it) {
word += *it;
}
请注意,它char
可能是无符号的,但std::isdigit()
需要一个正值。如果char
使用我的第二个名字签名通常会导致未定义的行为。为避免此问题,应将char
pass to转换为first。std::isdigit()
unsigned char
在循环中再次使用 get() 来检查它是否是某个字符:这里是代码
while(is.good() && !isdigit(is.peek()))
{
is.get(c);
word+=c;
if(is.get(c))
{
is.seekg(-1,ios::cur) //move back get pointer if its not end of file
}
}
怎么样:
#include<cctype>
#include<fstream>
#include<iostream>
#include<string>
int main() {
std::ifstream fp("text.txt");
std::string word;
char c;
// while I am able to read a char...
while(fp>>c) {
//... if the char is a digit, stop reading...
if(std::isdigit(c))
break;
//... otherwise append it to my word string
word += c;
}
// close your files (or learn about scope-based destruction)
fp.close();
// print the resulting word
std::cout<<word<<std::endl;
return 0;
}
编译:g++ example.cpp
样本输入 ( text.txt
):
a
b
c
d
e
f
8
样本输出:
abcdef
问题是,is.good()
在您读取失败之后,它才会变为错误。所以在你读完最后一个字符之后,is.good()
仍然是真的,你再次循环读取另一个字符(失败),所以你再次附加相同的字符。
为避免这种情况,您需要在is.good()
读取(或偷看)下一个字符后调用——如果它为假,则没有下一个字符:
ifstream is;char c;
is.open("text.txt");
while(!isdigit(is.peek()) && is.good())
{ is.get(c)
word+=c;
}
或更简单且等效的:
ifstream is;char c;
is.open("text.txt");
while (is >> c && !isdigit(c))
word+=c;