确切地说,如何解释 std::getline(stream, string) 函数在C++中填充的字符串

Exactly how to interpret the string filled in by std::getline(stream, string) function in C++

本文关键字:函数 string C++ 字符串 填充 stream std 何解释 解释 getline      更新时间:2023-10-16

我看到了一些我无法理解的东西。

#include <iostream>
#include <fstream>
#include <string>

int main()
{
std::ifstream someStream;
someStream.open("testfile"); 
std::string current_line;
if ( someStream.good() )
{
while (std::getline(someStream, current_line))
{
std::cout << current_line << "n";
std::cout << std::string(std::begin(current_line), std::begin(current_line) + sizeof(long));
std::cout << "n";
}
}
return 0;
}

当前目录中的testfile具有该格式。

319528800,string1
319528801,string2
319528801,string3
319528802,string4

我想解决的问题:

我想在每行上提取第一个逗号之前的数字,然后使用每个数字作为键制作地图。我知道这些数字是重复的。 然而,我无法制作地图,它一直只插入第一个数字。

上面的代码想要打印出每行第一个逗号之前的数字。但它无法做到这一点。但是,我正在尝试打印每次正确调用std::getline时返回的字符串,并且我能够打印当前行。

编辑:我太过分了。我确实忽略了sizeofstd::size始终是预定义类型的const

下面是一些在当前行中查找逗号的代码

while (std::getline(someStream, current_line))
{
std::cout << current_line << "n";
// get position of comma
size_t pos = current_line.find(',');
// get string before comma
std::string tmp = current_line.substr(0, pos);
// convert to long
long num = stol(tmp);

请注意,此代码假设输入中有一个逗号,如果没有逗号,它可能会崩溃。您应该始终检查输入数据。

您所需要的只是:

long value = std::stol(current_line);

std::stol跳过前导空格,然后将剩余文本分析为整数值。当它命中不能是整数一部分的字符时,它将停止。所以当它击中那个,时它会停止.

你把解析搞得太复杂了。为了解析来自流的条目,您可以执行以下操作

#include <fstream>
#include <iostream>
#include <string>
int main()
{
std::ifstream someStream("testfile");
char sep;
unsigned long num;
std::string current_line;
while (someStream >> num >> sep >> current_line) {
if (sep != ',')
break; // Bad separator
std::cout << num << ", " << current_line << "n";
}
return 0;
}

更喜欢制作一个代表每一行的结构

struct input_line {
long number;
std::string str;
};
std::istream& operator>>(std::istream& in, input_line& line) {
char comma;
if (in >> line.number >> comma >> line.str) {
if (number < 0) throw std::runtime_error("invalid number ");
if (comma != ',') throw std::runtime_error("missing comma");
if (str.empty()) throw std::runtime_error("missing string");
}
}

然后阅读变得微不足道:

int main() {
std::ifstream someStream("testfile"); 
input_line line;
while(someStream >> line)
std::cout << line.number << ',' << line.str << 'n';
}

从这个想法发展而来,我们实际上可以使用istream_iterator直接从文件中读取到地图中。

struct input_line {
long number;
std::string str;
operator std::pair<long, std::string>() const &
{ return {number, str}; }
operator std::pair<long, std::string>&&() &&
{ return {number, std::move(str)}; }
};
std::istream& operator>>(std::istream& in, input_line& line) {
char comma;
if (in >> line.number >> comma >> line.str) {
if (number < 0) throw std::runtime_error("invalid number ");
if (comma != ',') throw std::runtime_error("missing comma");
if (str.empty()) throw std::runtime_error("missing string");
}
}
int main() {
std::ifstream someStream("testfile"); 
std::istream_iterator<input_line> first(someStream);
std::map<long, std::string> map(first, {});
for(auto&& pair : map) 
std::cout << pair.first << ',' << pair.second << 'n';
}
相关文章: