从输入流中“丢弃”已读取的值是否可行?

3

我处理一些数据,其中列中的数据如下:

1 -0.004002415458937208 0.0035676328502415523
2 -0.004002415796209478 0.0035676331876702957
....

我只对最后两个值感兴趣。通常,我会将这些值读为:

std::ifstream file(file_name);
double a, b;
for (lines) {
    //      | throwing away the first value by reading it to `a`
    file >> a >> a >> b;
    store(a, b);
}

我不确定这对其他人来说是否易读,当数据结构未知时可能被视为错误。 我是否可以做些什么使其更加明确,以便真正丢弃第一个读取的值? 我希望得到以下内容,但没有任何效果:
file >> double() >> a >> b; // I hoped I could create some r-value kind of thing and discard the data in there
file >> NULL >> a >> b;

3
_是一个有效的标识符,我曾见过它被用作变量的占位符。其他类似的名称包括:discardedignoredconsumedunuseddestroyer_of_hope(好吧,最后一个不算)。 - jaggedSpire
我定义了一个名为“eater”的变量,它会吃掉不需要的输入。 - NathanOliver
我认为为此创建一个变量是多余的,而且不使用它可能会产生警告(我意识到实际上并没有)。这可能是一个不错的解决方法。 - pingul
如果你是从文件中读取,为什么要使用“from std::cin”? - Rama
3
file >> junk >>... 可以起到作用。这是我丢弃输入的做法。 - Topological Sort
显示剩余3条评论
3个回答

10

如果您不想显式创建一个变量来被忽略,而且您觉得在调用流操作时显式地忽略值太啰嗦了,那么您可以利用重载 std::istreamoperator>>,它接受一个 std::istream&(*)(std::istream&) 函数指针:

template <typename CharT>
std::basic_istream<CharT>& ignore(std::basic_istream<CharT>& in){
    std::string ignoredValue;
    return in >> ignoredValue;
}

可用于:

std::cin >> ignore >> a >> b;

如果您想验证它的格式是否可以读入类型,请提供一个额外的模板参数来指定被忽略值的类型:

// default arguments to allow use of ignore without explicit type
template <typename T = std::string, typename CharT = char>
std::basic_istream<CharT>& ignore(std::basic_istream<CharT>& in){
    T ignoredValue;
    return in >> ignoredValue;
}

用法如下:

std::cin >> ignore >> a >> b;
// and
std::cin >> ignore<int> >> a >> b;

在coliru上的演示


9
你可以使用 std::istream::ignore 方法。
例如:
file.ignore(std::numeric_limits<std::streamsize>::max(), ' '); //columns are separated with space so passing it as the delimiter.
file >> a >> b;

好的回答。我觉得它有点啰嗦,而且违背了短语“file >> a >> a >> b”的目的。 - pingul
@pingul 嗯,你可以创建一个自定义流操作器来使语法更漂亮。看看这个答案。它应该很容易适应你的需求:http://stackoverflow.com/a/29414164/2355119 - Dim_ov

1
你可以使用file::ignore(255, ' ')来忽略字符直到下一个空格。
std::ifstream file(file_name);
double a, b;
for (lines) {
    //  skip first value until space
    file.ignore(255, ' ');
    file >> a >> b;
    store(a, b);
}

或者你可以使用一个辅助变量来存储第一个值:
std::ifstream file(file_name);
double aux, a, b;
for (lines) {
    //  skip first value
    file >> aux >> a >> b;
    store(a, b);
}

5
file.ignore() 应该使用 std::numeric_limits<std::streamsize>::max() 以忽略所有字符,直到下一个空格。使用数字 255 会人为地限制你最多只能忽略 255 个字符。 - Karl Nicoll
我认为这不是问题,因为第一个数据是整数。问题可能出现在行以1个或多个空格开头的情况下。在这种情况下,代码无法按照需要工作! - Jesus R. Leal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接