从文件中读取C++双引号

4

我正在尝试使用C ++读取CSV文件并进行计算,然后将结果输出到另一个CSV文件。一切都很顺利,但当程序读取一行时:

<a href="http://www.google.com" target="_blank">google</a>

我希望能够查看程序读取的内容,因此我输出了该字符串,结果显示:

<a href=""http://www.google.com"" target=""_blank"">google</a>

基本上它会将每个双引号都加倍?那我该怎么解决呢?
编辑:
这是我的代码:
int main() 
{
    ifstream read;
    ofstream write;
    string line;
    string cell;
    int col = 0;
    string temp;
    string links;
    read.open("Book1.csv");
    write.open("output.csv");
    if (read.is_open())
    {
        cout << "opened" <<endl ;
        getline(read, line);
        while(getline(read,temp))
        {
            stringstream line(temp);
            while (getline(line, cell, ','))
            {
                if (col > 9)
                {
                    links.pop_back();
                    write << links<<endl;
                    col = 0;
                    links = "";
                    break;
                }
                else
                {
                    if (cell != "")
                    {
                        if (col == 0)
                        {
                            write << cell<<',';
                        }
                        else if (col == 1)
                        {
                            write << cell<<',';
                        }
                            else
                    {
                            cell.erase(0, 1);
                            cell.pop_back();
                            links += cell;

                            links += '/';
                        }
                        cout << cell << endl;
                    }
                    col += 1;
                }
            }
        }       
    }
    else 
    {
        cout << "failed" << endl;
    }       
    read.close();
    write.close();  
}

1
你是如何从文件中读取数据的?使用标准库调用不会“意外”发生这种情况。请参考:http://ideone.com/j3jJrO 了解示例。 - Chad
@Chad 我使用了getline和stringstream。哦,顺便问一下如何让这些在注释中的灰色背景?我有点新来SO。 - andyz
@PaulMcKenzie 我实际上是从一个 csv 文件中读取数据。 - andyz
正如Chad和PaulMcKenzie在他们的例子中展示的那样,使用getline()从文件中读取通常不会导致引号加倍。如果您想要更多的调试帮助,您需要展示用于读取文件的确切代码(即将其放入您的问题中)。 - Edward
也许可以在这里找到有用的信息:https://dev59.com/-XNA5IYBdhLWcg3wBpDs - anatolyg
显示剩余2条评论
1个回答

3
这是完全正常的。字段(在你的csv文件中)内部的引号被用另一个引号转义,以生成有效的csv。
考虑以下csv数据:
123,"monitor 27"", Samsung",456

由于第二个字段包含一个逗号,因此需要将其放在引号中。但是由于字段内有引号,这些引号需要用另一个引号进行转义。
因此,增加的引号不是读取时添加的,它们已经存在于您的csv文件中(但是在解析后,csv查看器只会显示一个引号)。
如果您要将此字符串输出到另一个csv文件中,可以保留双引号,只需确保整个字段也被引号包围即可。
更新:(发布代码后)
首先,我假设你所发布的第二个字符串也被引号包围,例如:
"<a href=""http://www.google.com"" target=""_blank"">google</a>"

否则,您将拥有无效的CSV数据。
为了解析CSV,我们不能只在每个“,”上拆分,因为字段中可能会有一个。
假设我们有以下字段:
123
monitor 27", Samsung
456

为了将它们写入有效的CSV行,第二个字段必须用引号括起来,因为其中包含逗号。如果在引号内有引号,那么这些引号需要用另一个引号进行转义。因此我们得到:

123,"monitor 27"", Samsung",456

如果在 27" 后没有第二个引号,csv 将无效且无法解析。

为了正确地扫描 csv 行,您需要检查每个字节。以下是一些伪代码,这也将清楚地说明为什么必须有两个引号(假设没有多行字段):

read a line

bool bInsideQuotes = false

loop over chars
  if character == '"'
    bInsideQuotes = !bInsideQuotes
  if character == ',' and !bInsideQuotes
    found a field separator

那样您就可以跳过字段内部的逗号了。现在也很容易理解为什么字段内的引号需要用额外的引号进行转义: bInsideQuotes27" 处变为 false,而第二个引号 (27"") 再次强制使 bInsideQuotes 变为 true (我们仍然在一个字段内)。
现在,要将原始字符串写回,您无需改变任何内容。只需将其按原始文件读取后写入第二个文件中,您的 csv 将保持有效。
要使用该字符串,请删除两个外部引号并将每两个引号替换为一个引号。

我将其输出到CSV文件中,但仍然有两个双引号? - andyz
@andyz - 是的,如果字段被引号包围,那么内部的引号需要加倍:1253,"<a href=""http://www.google.com"" target=""_blank"">google</a>",456。但是也不要忘记外面的引号。 (可能要查看记事本中的原始 CSV 文件,以查看如何引用所有内容) - Danny_ds
那么我该如何删除我不需要的引号呢?即与输入相同的格式。 - andyz
@andyz - 如果你将该字符串写回到另一个csv文件中,你也需要保留这些引号。此外,在读取时,请确保不要在带引号的字段内拆分逗号。我会在15分钟内更新我的答案(被叫走了)。 - Danny_ds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接