C++ CSV 行,带逗号和双引号内的字符串

dim*_*zen 5 c++ csv quotes double comma

我正在用 C++ 读取 CSV 文件,行格式如下:

“主要,次要,第三”,“主要”,,“次要”,18, 4, 0, 0, 0

(注意空值)

当我做:

while (std::getline(ss, csvElement, ',')) {
   csvColumn.push_back(csvElement);
}
Run Code Online (Sandbox Code Playgroud)

这会将第一个字符串分成不正确的部分。

迭代时如何保留字符串?我尝试将上述方法结合起来,同时还抓取了由双引号分隔的行,但我得到了疯狂的结果。

use*_*113 7

使用std::quoted允许您从输入流读取带引号的字符串。

#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::stringstream ss;
    ss << "\"Primary, Secondary, Third\", \"Primary\", , \"Secondary\", 18, 4, 0, 0, 0";

    while (ss >> std::ws) {
        std::string csvElement;

        if (ss.peek() == '"') {
            ss >> std::quoted(csvElement);
            std::string discard;
            std::getline(ss, discard, ',');
        }
        else {
            std::getline(ss, csvElement, ',');
        }

        std::cout << csvElement << "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

实例

需要注意的是,仅当值的第一个非空白字符是双引号时才会提取带引号的字符串。此外,带引号的字符串后面的任何字符都将被丢弃,直到下一个逗号为止。


Chr*_*phe 2

您需要根据是否位于引号之间来解释逗号。这对于 来说太复杂了getline()

解决方案是使用 读取整行getline(),并通过逐字符迭代字符串来解析该行,并维护一个指示符,无论您是否在双引号之间。

这是第一个“原始”示例(字段中的双引号不会被删除,并且转义字符不会被解释):

string line; 
while (std::getline(cin, line)) {        // read full line
    const char *mystart=line.c_str();    // prepare to parse the line - start is position of begin of field
    bool instring{false};                
    for (const char* p=mystart; *p; p++) {  // iterate through the string
        if (*p=='"')                        // toggle flag if we're btw double quote
            instring = !instring;     
        else if (*p==',' && !instring) {    // if comma OUTSIDE double quote
            csvColumn.push_back(string(mystart,p-mystart));  // keep the field
            mystart=p+1;                    // and start parsing next one
        }
    }
csvColumn.push_back(string(mystart));   // last field delimited by end of line instead of comma
}
Run Code Online (Sandbox Code Playgroud)

在线演示