C++:读取由 ; 分隔的 CSV 文件和\n
C++: Read CSV-file separated by ; AND \n
抱歉,如果这纯粹是愚蠢,但我遇到了通过 C++ 读取文件的问题。
这是我想要阅读的 CSV 数据:
5;1;0;3;3;5;5;3;3;3;3;2;3;3;0
5;1;0;3;3;5;0;3;3;3;3;2;0;0;3
5;1;1;3;3;0;0;0;0;3;5;2;3;3;3
0;3;5;5;0;2;0;3;3;0;5;1;1;0;0
0;0;3;5;5;2;0;0;0;0;5;5;1;1;0
0;0;0;0;5;2;0;0;0;0;0;5;5;1;0
;;;;;;;;;;;;;;
Code;Bezeichnung;Kosten;;;;;;;;;;;;
0;Ebene;6;;;;;;;;;;;;
1;Fluss;10; (begrenzt nutzbar);;;;;;;;;;;
2;Weg;2;;;;;;;;;;;;
3;Wald;8;;;;;;;;;;;;
4;Brücke;5;;;;;;;;;;;;
5;Felswand;12;;;;;;;;;;;;
在这里,我想读取第一个值(用 ;;;; 分隔)并将其存储在二维数组中。如果它被“;”完全分隔,那将不是问题。但是如果使用
while (getline(csvread, s, ';'))
{
[...]
}
我得到这样的信息:{5}{1}{0}{3}{3}{5}{5}{3}{3}{3}{3}{2}{3}{3}{0\n5}{1}
所以它基本上保存了换行符并且不认为它是分隔符。
即使您有两个定界符,是否还有使用 getline 的选项?还是我完全离开了?
我还考虑过将它逐行读取为一个字符串,添加一个;到字符串并将其重写到文件中,以便使用 ; 重用 getline。但这并不是最好的选择,对吧?
您应该分别进行 '\n'
和 ';'
拆分:
// here split into lines by '\n'
while (getline(csvread, line, '\n'))
{
// in here, split line by ;
std::vector<std::string> elems;
boost::split(elems, line, boost::is_any_of(";"));
// do something with elems
}
您可以使用像这样的拆分函数:
std::vector<std::string> split(const std::string& source, const std::string& delimiter){
std::vector<std::string> result;
size_t last = 0;
size_t next = 0;
while ((next = source.find(delimiter, last)) != std::string::npos){
result.push_back(source.substr(last, next - last));
last = next + delimiter.length();
}
result.push_back(source.substr(last));
return result;
}
现在只需:
std::vector<std::vector<std::string>> parsedCSV;
while (getline(csvread, s, '\n'))
{
parsedCSV.push_back(split(s,";"));
}
我最近也不得不阅读 csv 数据,偶然发现了同样的“问题”。这是我所做的:
- 使用
getline(csvread, s)
读取整行,这将读取到第一个换行符。
- 每次出现
;
时拆分字符串,我使用 this Whosebug 答案作为拆分字符串的灵感,代码也列在下面。
我不太关心性能,因为我只需要 运行 这个程序一次,我不会评论这个变通方法的速度。
祝你好运!
编辑: 显然 Boost 提供了拆分字符串的代码,这可能更清晰,如果您想避免使用 Boost,请考虑下面的代码。
#include <string>
#include <sstream>
#include <vector>
// source:
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
尝试这样的事情:
std::vector<std::string> cells;
while (getline(csvread, s) ){
boost::split(cells, s, boost::is_any_of(";"));
....
}
抱歉,如果这纯粹是愚蠢,但我遇到了通过 C++ 读取文件的问题。 这是我想要阅读的 CSV 数据:
5;1;0;3;3;5;5;3;3;3;3;2;3;3;0
5;1;0;3;3;5;0;3;3;3;3;2;0;0;3
5;1;1;3;3;0;0;0;0;3;5;2;3;3;3
0;3;5;5;0;2;0;3;3;0;5;1;1;0;0
0;0;3;5;5;2;0;0;0;0;5;5;1;1;0
0;0;0;0;5;2;0;0;0;0;0;5;5;1;0
;;;;;;;;;;;;;;
Code;Bezeichnung;Kosten;;;;;;;;;;;;
0;Ebene;6;;;;;;;;;;;;
1;Fluss;10; (begrenzt nutzbar);;;;;;;;;;;
2;Weg;2;;;;;;;;;;;;
3;Wald;8;;;;;;;;;;;;
4;Brücke;5;;;;;;;;;;;;
5;Felswand;12;;;;;;;;;;;;
在这里,我想读取第一个值(用 ;;;; 分隔)并将其存储在二维数组中。如果它被“;”完全分隔,那将不是问题。但是如果使用
while (getline(csvread, s, ';'))
{
[...]
}
我得到这样的信息:{5}{1}{0}{3}{3}{5}{5}{3}{3}{3}{3}{2}{3}{3}{0\n5}{1}
所以它基本上保存了换行符并且不认为它是分隔符。
即使您有两个定界符,是否还有使用 getline 的选项?还是我完全离开了? 我还考虑过将它逐行读取为一个字符串,添加一个;到字符串并将其重写到文件中,以便使用 ; 重用 getline。但这并不是最好的选择,对吧?
您应该分别进行 '\n'
和 ';'
拆分:
// here split into lines by '\n'
while (getline(csvread, line, '\n'))
{
// in here, split line by ;
std::vector<std::string> elems;
boost::split(elems, line, boost::is_any_of(";"));
// do something with elems
}
您可以使用像这样的拆分函数:
std::vector<std::string> split(const std::string& source, const std::string& delimiter){
std::vector<std::string> result;
size_t last = 0;
size_t next = 0;
while ((next = source.find(delimiter, last)) != std::string::npos){
result.push_back(source.substr(last, next - last));
last = next + delimiter.length();
}
result.push_back(source.substr(last));
return result;
}
现在只需:
std::vector<std::vector<std::string>> parsedCSV;
while (getline(csvread, s, '\n'))
{
parsedCSV.push_back(split(s,";"));
}
我最近也不得不阅读 csv 数据,偶然发现了同样的“问题”。这是我所做的:
- 使用
getline(csvread, s)
读取整行,这将读取到第一个换行符。 - 每次出现
;
时拆分字符串,我使用 this Whosebug 答案作为拆分字符串的灵感,代码也列在下面。
我不太关心性能,因为我只需要 运行 这个程序一次,我不会评论这个变通方法的速度。
祝你好运!
编辑: 显然 Boost 提供了拆分字符串的代码,这可能更清晰,如果您想避免使用 Boost,请考虑下面的代码。
#include <string>
#include <sstream>
#include <vector>
// source:
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
尝试这样的事情:
std::vector<std::string> cells;
while (getline(csvread, s) ){
boost::split(cells, s, boost::is_any_of(";"));
....
}