如何读取单行内具有多个分隔符的文件
How to read a file with multiple delimiters within a single line
我正在尝试读取每行有多个分隔符的文件。下面是数据
2,22:11
3,33:11
4,44:11
5,55:11
6,66:11
7,77:11
8,88:11
9,99:11
10,00:11
11,011:11
12,022:11
13,033:11
14,044:11
15,055:11
16,066:11
17,077:11
18,088:11
19,099:11
代码在
下面在这里,我试图先用逗号作为分隔符来读取行,然后是冒号。
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::string line;
std::string token;
std::ifstream infile;
infile.open("./data.txt");
while (std::getline(infile, line,',')) {
std::cout << line << std::endl;
while(getline(infile, token, ':'))
{
std::cout << " : " << token;
}
}
}
但是代码有一个问题,因为它跳过了第一行。另外,如果我注释第二个while循环,则只打印第一行,下面是输出
我不知道代码到底哪里出了问题
输出2
: 22 : 11
3,33 : 11
4,44 : 11
5,55 : 11
6,66 : 11
7,77 : 11
8,88 : 11
9,99 : 11
10,00 : 11
11,011 : 11
12,022 : 11
13,033 : 11
14,044 : 11
15,055 : 11
16,066 : 11
17,077 : 11
18,088 : 11
19,099 : 11
为什么是两个while
?
你的问题是你永远在重复第二个while。执行第一个while
只得到第一个2
,第二个while执行到文件末尾。
您可以使用单个while
完成所有操作;就像
#include <fstream>
#include <iostream>
using namespace std;
int main() {
std::string line;
std::string token;
std::string num;
ifstream infile;
infile.open("a.txt");
while ( getline(infile, line,',')
&& getline(infile, token, ':')
&& getline(infile, num) )
cout << line << ',' << token << ':' << num << endl;
}
问题来自于您使用std::getline
两次的事实。
在开始时进入第一个循环。第一次调用std::getline
返回您所期望的:第一行直到 ,
分隔符。
然后在嵌套循环中输入第二个std::getline
,以获得该行的其余部分。但问题是,你永远不会离开第二个循环,直到文件结束。因此,您读取所有文件的:
分隔符。
当第二个std:getline
结束到文件末尾时,它离开嵌套循环。
因为你已经读取了所有的文件,所以没有什么需要读取的了,第一个循环直接退出。
下面是一些调试来帮助你理解上下文:
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::string line;
std::string token;
std::ifstream infile;
infile.open("./data.txt");
while (std::getline(infile, line, ',')) {
std::cout << "First loop : " << line << std::endl;
while(getline(infile, token, ':'))
{
std::cout << "Inner loop : " << token << std::endl;
}
}
}
要打印的第一行是:
First loop : 2
Inner loop : 22
Inner loop : 11
3,33
Inner loop : 11
4,44
你可以清楚地看到它直到末尾才退出第二个循环。
我建议读取整行,不考虑分隔符,然后,然后使用定制的函数将字符串拆分为token。这样既方便又干净。
解决方案:
#include <fstream>
#include <list>
#include <iostream>
#include <string>
struct line_content {
std::string line_number;
std::string token;
std::string value;
};
struct line_content tokenize_line(const std::string& line)
{
line_content l;
auto comma_pos = line.find(',');
l.line_number = line.substr(0, comma_pos);
auto point_pos = line.find(':');
l.token = line.substr(comma_pos + 1, point_pos - comma_pos);
l.value = line.substr(point_pos + 1);
return l;
}
void print_tokens(const std::list<line_content>& tokens)
{
for (const auto& line: tokens) {
std::cout << "Line number : " << line.line_number << std::endl;
std::cout << "Token : " << line.token << std::endl;
std::cout << "Value : " << line.value << std::endl;
}
}
int main() {
std::string line;
std::ifstream infile;
std::list<line_content> tokens;
infile.open("./data.txt");
while (std::getline(infile, line)) {
tokens.push_back(tokenize_line(line));
}
print_tokens(tokens);
return 0;
}
我认为你应该能做你想做的事。
g++ -Wall -Wextra --std=c++1y <your c++ file>
如果您想在多个分隔符上分割字符串,而不必担心分隔符的顺序,您可以使用std::string::find_first_of()
#include <fstream>
#include <iostream>
#include <streambuf>
#include <string>
int
main()
{
std::ifstream f("./data.txt");
std::string fstring = std::string(std::istreambuf_iterator<char>(f),
std::istreambuf_iterator<char>());
std::size_t next, pos = 0;
while((next = fstring.find_first_of(",:n", pos)) != std::string::npos)
{
std::cout.write(&fstring[pos], ++next - pos);
pos = next;
}
std::cout << &fstring[pos] << 'n';
return 0;
}
相关文章:
- C++使用分隔符读取文件
- 到达分隔符时跳到文本文件的下一行
- 使用空格分隔符从文本文件将对象读入数组
- 使用任意分隔符从文件流读取
- 使用 C++ 读取具有两个连续分隔符的 csv 文件
- 通过自定义分隔符从文件中读取对象数组
- 使用不同类型的分隔符从.txt文件中读取输入
- 如何在没有分隔符的大文本文件中查找所有字典单词
- 将 OpenCV MAT 保存到 TXT 文件作为不带分隔符的十六进制值
- 如何在C++中正确解析带有多个分隔符的文本文件
- 从没有分隔符 C++ 的文件读取数字出现次数
- 生成文件,缺少分隔符错误
- 生成文件错误:缺少分隔符
- 检测 CSV 文件中的记录/行分隔符
- C++ 使用多个分隔符存储输入文件
- 用指定的分隔符按线解析文本文件
- 如何获取标准 C/C++ 中的文件分隔符符号:/ 或 \
- 在C++中搜索二进制文件分隔符时出现不正确的偏移量
- C++具有混合分隔符和数据类型的文件输入
- 我的生成文件中缺少分隔符