所以我在这个网站上看到了很多解决方案和有关从C ++文本文件中读取的教程,但还没有找到解决我问题的方法。我是C ++的新手,所以我觉得我很难拼凑一些文档来理解这一切。
我要做的是读取文本文件编号,同时忽略文件中用“#”表示的注释。所以示例文件看起来像:
#here is my comment
20 30 40 50
#this is my last comment
60 70 80 90
当没有任何评论时,我的代码可以很好地读取数字,但我不理解解析流足以忽略评论。它现在是一种黑客解决方案。
/////////////////////// Read the file ///////////////////////
std::string line;
if (input_file.is_open())
{
//While we can still read the file
while (std::getline(input_file, line))
{
std::istringstream iss(line);
float num; // The number in the line
//while the iss is a number
while ((iss >> num))
{
//look at the number
}
}
}
else
{
std::cout << "Unable to open file";
}
/////////////////////// done reading file /////////////////
我是否可以将评论处理与此解决方案结合使用,还是需要采用不同的方法?任何建议都会很棒,谢谢。
答案 0 :(得分:3)
如果您的文件始终在第一列中包含#
,那么只需测试一下,如果该行以#
开头,请执行以下操作:
while (std::getline(input_file, line))
{
if (line[0] != "#" )
{
std::istringstream iss(line);
float num; // The number in the line
//while the iss is a number
while ((iss >> num))
{
//look at the number
}
}
}
虽然修剪前导和尾随空格的行是明智的,例如:Remove spaces from std::string in C++
答案 1 :(得分:2)
如果这只是一个使用,对于像你这样的面向行的输入, 最简单的解决方案就是从你刚才的行中删除评论 读:
line.erase( std::find( line.begin(), line.end(), '#' ), line.end() );
更通用的解决方案是使用过滤streambuf,某些东西 喜欢:
class FilterCommentsStreambuf : public std::streambuf
{
std::istream& myOwner;
std::streambuf* mySource;
char myCommentChar;
char myBuffer;
protected:
int underflow()
{
int const eof = std::traits_type::eof();
int results = mySource->sbumpc();
if ( results == myCommentChar ) {
while ( results != eof && results != '\n') {
results = mySource->sbumpc(0;
}
}
if ( results != eof ) {
myBuffer = results;
setg( &myBuffer, &myBuffer, &myBuffer + 1 );
}
return results;
}
public:
FilterCommentsStreambuf( std::istream& source,
char comment = '#' )
: myOwner( source )
, mySource( source.rdbuf() )
, myCommentChar( comment )
{
myOwner.rdbuf( this );
}
~FilterCommentsStreambuf()
{
myOwner.rdbuf( mySource );
}
};
在这种情况下,您甚至可以放弃getline
:
FilterCommentsStreambuf filter( input_file );
double num;
while ( input_file >> num || !input_file.eof() ) {
if ( ! input_file ) {
// Formatting error, output error message, clear the
// error, and resynchronize the input---probably by
// ignore'ing until end of line.
} else {
// Do something with the number...
}
}
(在这种情况下,我发现跟踪行号也很有用
FilterCommentsStreambuf
。那样你就错了
邮件。)
答案 2 :(得分:0)
&#34;读取aline并将其解析为字符串&#34;的替代方法,可以使用流本身作为传入缓冲区:
while(input_file)
{
int n = 0;
char c;
input_file >> c; // will skip spaces ad read the first non-blank
if(c == '#')
{
while(c!='\n' && input_file) input_file.get(c);
continue; //may be not soooo beautiful, but does not introduce useless dynamic memory
}
//c is part of something else but comment, so give it back to parse it as number
input_file.unget(); //< this is what all the fuss is about!
if(input_file >> n)
{
// look at the nunber
continue;
}
// something else, but not an integer is there ....
// if you cannot recover the lopop will exit
}