C++读取csv,将逗号替换为零

C++ reading csv replacing commas with zeros

本文关键字:替换 读取 csv C++      更新时间:2023-10-16

我正试图编写一个程序来返回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;
}

然而,仍然存在逗号被零替换的问题,因此count没有返回正确的列数

循环后:

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;
}

您究竟是如何得出逗号被零取代的结论的?

您在第一个while循环中读取了整个文件。然后第二个while循环什么也不做,因为它在文件的末尾。

您在计算行数时已经读取了整个文件。因此,当你进入下一个循环,计算逗号时,就没有数据可以读取了。

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

在代码的第一个片段中,您尝试读取文件两次,而不返回到文件开始。在第二种情况下,当您尝试对列(逗号)进行计数时,您使用带有","作为分隔符的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 filen";
    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

您已经打开文件,然后使用

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

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

例如,当您呼叫时

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

您已经超出了文件的末尾,所以count将为零。

可以对FILE*使用std::rewind(myfile),对流使用std::fseek(myfile, 0, SEEK_SET),以返回到文件的开头
你可以边读边数逗号。您可以将其分解为两个函数,并为每个计数重新打开文件——一个用于行,一个用于逗号计数。