只读取文本文件中整行的第一个整数

Reading only first integer from whole line in text file

如果有这样的文本文件:

3       size of group
10     individual therapy time(min)
15     group therapy time(min)
25      new client probability percentage
500     individual therapy cost
300     group therapy cost

有没有办法只读取文本行的第一个整数并跳转到另一行?

我尝试过的:

settingsFile >> groupSize >> trash >> trash >> trash;
settingsFile >> indTime >> trash >> trash >> trash;
settingsFile >> newClientProb >> trash >> trash >> trash >> trash;
settingsFile >> indTherapyCost >> trash >> trash >> trash;
settingsFile >> groupTherapyCost >> trash >> trash >> trash;

而且在我看来,这不是读取文本文件的好方法,因为如果我从文本文件中删除一个 trash 字符串,整个读取将失败。

您可以像这样使用 std::getline 忽略该行的其余部分:

settingsFile >> groupSize;
std::getline(settingsFile, trash);
settingsFile >> indTime;
std::getline(settingsFile, trash);
settingsFile >> newClientProb;
std::getline(settingsFile, trash);
settingsFile >> indTherapyCost;
std::getline(settingsFile, trash);
settingsFile >> groupTherapyCost;
std::getline(settingsFile, trash);

另一种方法是将文件逐行读取到一个临时字符串变量中,然后利用 string_stream 解析该字符串开头的整数,但这有点乏味。

如果 C++11 可用,则可以使用 std::stoi 轻松完成第二步,最后得到如下代码(这次在循环中):

for (std::string line; std::getline(settingsFile, line); ) {
    int value = std::stoi(line);
    ...
}

或引入新功能readIntLine:

template< class CharT, class Traits>
int readIntLine(std::basic_istream<CharT,Traits>& input) {
    std::basic_string<CharT,Traits> line;
    std::getline(settingsFile, line);
    return std::stoi(line);
}

那么,可以这样使用:

groupSize = readIntLine(settingsFile);
indTime = readIntLine(settingsFile);
newClientProb = readIntLine(settingsFile);
indTherapyCost = readIntLine(settingsFile);
groupTherapyCost = readIntLine(settingsFile);

您可以只读取整数,然后 ignore() 该行的其余部分:

using NL = std::numeric_limits<std::streamsize>;
while ((in >> value).ignore(NL::max(), '\n')) {
   ...
}

需要使用 max(),因为此值表示 "as many characters as needed" 而不是使用某个较大的上限。把这个逻辑封装成操纵器可能也是合理的:

std:: istream& ignl(std::istream& in) {
    return in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
...
if (in >> value0 >> ignl
    && in >> value1 >> ignl
    // ...
    ) {
    // do something with the result
}

当然,在使用输入之前始终需要检查输入:否则在出现故障时将处理随机值。