C ++读取csv用零替换逗号

时间:2016-04-12 12:15:13

标签: c++ csv

我试图编写一个程序来返回csv文件中的行数和列数。以下是我目前的代码:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
    string line;
    ifstream myfile("ETF_Corrsv2.csv");

    if (myfile.is_open())
    {
        int counter = 0;
        while (getline(myfile, line)) { // To get the number of lines in the file
            counter++;
            cout << counter;
        }


        //int baz[5][5] = {};
        while (getline(myfile, line, ','))
        {

            int count = 0;
            cout << line;
            for (int i = 0; i < line.size(); i++)
                if (line[i] == ',')
                    count++;

            cout << count;
        }

        myfile.close();
    }

    else cout << "Unable to open file";

    return 0;
}

第一部分工作正常,计数器适当地返回行数。但是count不会返回正确的逗号数量。当使用cout显示行时,它显示逗号似乎已被零替换,但是当我用Notepad ++打开文件时,逗号就在那里。发生了什么事?

编辑:更改了代码,使所有操作都在一个while循环中:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
    string line;
    ifstream myfile("ETF_Corrsv2.csv");

    if (myfile.is_open())
    {
        int counter = 0;

        while (getline(myfile, line, ',')) { // To get the number of lines in the file
            counter++;
            cout << counter;
            int count = 0;
            cout << line;
            for (int i = 0; i < line.size(); i++)
                if (line[i] == ',')
                    count++;
            cout << count;
        }

        myfile.close();
    }

    else cout << "Unable to open file";

    return 0;
}

但是仍然存在逗号被零替换的问题,尽管如此计数并不能返回正确的列数

5 个答案:

答案 0 :(得分:0)

此循环后:

while (getline(myfile, line)) { // To get the number of lines in the file
    counter++;
    cout << counter;
}

该文件已被完全读取,没有更多行可用。因此,您必须找到另一种方法,例如将文件存储在字符串中,然后对它们进行计数或在第一个while中完成所有工作,或者重新打开它。

我认为在第一个循环中完成所有工作是最佳方式。

可能的解决方案(未经测试):

while (getline(myfile, line)) { // To get the number of lines in the file
    counter++;
    cout << counter;
    int cols_count= 0;
    cout << line;
    for (int i = 0; i < line.size(); i++){
        if (line[i] == ',')
            cols_count++;
    }
    cout << cols_count;
}

答案 1 :(得分:0)

你究竟是如何得出逗号被零替换的结论?

您在第一个while循环中读取整个文件。然后第二个while循环不执行任何操作,因为它位于文件末尾。

答案 2 :(得分:0)

您在计算行时已读取整个文件。因此,当您进入下一个计算逗号的循环时,没有剩余的数据可供阅读。

我建议您将逗号计数循环放在行计数循环中。或者,对于格式良好的CSV文件,所有行上都有相同数量的逗号,因此您只需要检查一行以查找逗号的数量。

答案 3 :(得分:0)

您已打开文件,然后使用

  while (getline(myfile, line)) { // To get the number of lines in the file
        counter++;
        cout << counter;
    }

读到文件的末尾。 任何进一步的读取都将“失败”。

e.g。当你打电话

while (getline(myfile, line, ','))
{
      //...
}

您已超出文件末尾,因此count将为零。

您可以使用std::rewind(myfile)表示文件*或std::fseek(myfile, 0, SEEK_SET)表示流可以返回文件的开头。
你可以在读行时计算逗号。 您可以将其分解为两个函数,并为每个计数重新打开文件 - 一个用于行,一个用于逗号计数。

答案 4 :(得分:0)

在代码的第一个片段中,您尝试两次读取文件而不返回文件启动。在第二种情况下,当您尝试计算列(逗号)时,使用带有','作为分隔符的getline,因此您的计数始终会在每列重新开始。

您可以尝试以下版本的代码:

#include <iostream>
#include <fstream>
#include <string>

using std::cout;
using std::cin;

int main() {
    std::ifstream myfile{"ETF_Corrsv2.csv"};

    if ( myfile.good() )
    {
        int rows = 0;           
        std::string line;

        while ( getline(myfile, line) ) {
            // skip empty lines
            if ( line.empty() )
                continue;
            ++rows;
            cout << "line " << rows;

            int columns = 0;    
            for (size_t i = 0; i < line.size(); i++)
                if (line[i] == ',')
                    columns++;
            // if the line is not terminated by a ','
            if  ( line[line.size() - 1] != ',' )
                columns++;

            cout << " has " << columns << " columns: "
                 << line << '\n';
        }
    }
    else
        cout << "Unable to open file\n";

    return 0;
}

这可以管理凌乱的输入文件,如:

45, 23, 48, 8.15e-8, 18, 21,
1, 4, New york, 18, 20

9, 8, Chicago, 6, 5, Up, Down, 2, 1

对外输出:

line 1 has 6 columns: 45, 23, 48, 8.15e-8, 18, 21,
line 2 has 5 columns: 1, 4, New york, 18, 20
line 3 has 9 columns: 9, 8, Chicago, 6, 5, Up, Down, 2, 1