【问题标题】:C++ Read double quotation marks from a fileC++ 从文件中读取双引号
【发布时间】:2016-02-10 04:55:24
【问题描述】:

所以我试图使用 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();  
}

【问题讨论】:

  • 你是如何读取文件的。使用标准库调用不会“偶然”发生这种情况。例如,请参阅:ideone.com/j3jJrO
  • @Chad 我使用了 getline 和 stringstream。哦,顺便说一句,我怎样才能在 cmets 中制作那些灰色背景的?我对 SO 有点陌生
  • 无法复制:ideone.com/SX4272
  • @PaulMcKenzie 我实际上是从 csv 文件中读取的
  • @andyz 所以给我们一行数据。与我的示例的唯一区别是“文件”是std::cin

标签: c++ csv double-quotes


【解决方案1】:

这是完全正常的。字段内的引号(在您的 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 行,您需要检查每个字节。这是一些伪代码,它也可以清楚地说明为什么必须有 2 个引号(假设没有多行字段):

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 将保持有效。

要使用该字符串,请删除 2 个外部引号并将每 2 个引号替换为 1 个引号。

【讨论】:

  • 我将它输出到一个 csv 文件,它仍然有 2 个双引号?
  • @andyz - 是的,如果字段用引号括起来,则里面的引号需要加倍:1253,"&lt;a href=""http://www.google.com"" target=""_blank""&gt;google&lt;/a&gt;",456。但也不要忘记外部引号。 (也许看看你在记事本中的原始 csv 文件,看看所有内容是如何引用的)
  • 那我如何删除不需要的引号呢?即与输入格式相同
  • @andyz - 如果您将该字符串写回另一个 csv,您也需要这些引号。此外,在阅读时,请确保不要在引用字段中拆分 ,。我会在 15 分钟内更新我的答案(在这里被叫走了)。
猜你喜欢
  • 2014-09-17
  • 2012-01-12
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多