4

我有一个 .csv 文件,它有 3 行和 5 列,值为 0、1、2、3、50 或 100。我将它从 excel 工作表保存到 .csv 文件。我正在尝试使用 C++ 读取 .csv 文件并根据最后三列值将 .csv 文件中的前两列值输出到文本文件中。我假设 .csv 文件看起来像

1,1,值,值,值

1,2,值,值,值

1,3,值,值,值

但是我找不到很多关于 .csv 文件格式的文档。

我查看了从 .csv 文件中的字段读取值?并使用了那里的一些代码。

这是我的代码:

#include <iostream>

#include <fstream>

using namespace std;

char separator;
int test_var;

struct Spaxel {
  int array1;
  int array2;
  int red;
  int blue_o2;
  int blue_o3;
};

Spaxel whole_list [3];

int main()
{
    // Reading in the file
    ifstream myfile("sample.csv");
    Spaxel data;
    int n = 0;
    cout << data.array1<< endl;
    myfile >> data.array1; // using as a test to see if it is working
    cout << data.array1<< endl;
    while (myfile >> data.array1)
    {
        // Storing the 5 variable and getting rid of commas
        cout<<"here?"<< endl;
        // Skip the separator, e.g. comma (',')
        myfile >> separator;

        // Read in next value.
        myfile >> data.array2;

        // Skip the separator
        myfile >> separator;

        // Read in next value.
        myfile >> data.red;

        // Skip the separator, e.g. comma (',')
        myfile >> separator;

        // Read in next value.
        myfile >> data.blue_o2;

        // Skip the separator
        myfile >> separator;

        // Read in next value.
        myfile >> data.blue_o3;

        // Ignore the newline, as it is still in the buffer.
        myfile.ignore(10000, '\n');

        // Storing values in an array to be printed out later into another file
        whole_list[n] = data;
        cout << whole_list[n].red << endl;
        n++;

        }
    myfile.close();

    // Putting contents of whole_list in an output file
    //whole_list[0].red = whole_list[0].array1 = whole_list[0].array2 = 1; this was a test     and it didn't work
    ofstream output("sample_out.txt");
    for (int n=0; n<3; n++) {
        if (whole_list[n].red == 1)
            output << whole_list[n].array1 <<","<< whole_list[n].array2<< endl;
    }
    return 0;
}

当我在 Xcode 中运行它时,它会打印三个 0(从 cout << data.array1<< endl; 和 cout << data.array1<< endl; 在 main() 的开头和从 return 0)但确实不输出任何文件。显然 .csv 文件没有被正确读取,输出文件也没有被正确写入。有什么建议么?

谢谢你的时间!

4

2 回答 2

4

您提供的代码中有几个问题区域:

  • 硬编码文件名。在没有“sample.csv”的目录中运行程序可能会导致ifstream您看到的失败。
  • 不检查是否myfile打开成功。
  • whole_list如果“sample.csv”有更多行,循环可以访问越界索引。

下面的重构代码虽然不是完全万无一失,但纠正了许多提到的问题。它应该能让你大部分时间到达那里。

#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;


struct Spaxel
{
  int array1;
  int array2;
  int red;
  int blue_o2;
  int blue_o3;
};

ostream& operator << (ostream &os, const Spaxel &rhs)
{
  os << rhs.array1
     << ','
     << rhs.array2
     << ','
     << rhs.red
     << ','
     << rhs.blue_o2
     << ','
     << rhs.blue_o3;

  return os;
}

istream& operator >> (istream &is, Spaxel &rhs)
{
  char delim;
  is >> rhs.array1
     >> delim
     >> rhs.array2
     >> delim
     >> rhs.red
     >> delim
     >> rhs.blue_o2
     >> delim
     >> rhs.blue_o3;

  return is;
}


int main(int argc, const char *argv[])
{
    if(argc < 2)
    {
      cout << "Usage: " << argv[0] << " filename\n";
      return 1;
    }

    const char *infilename = argv[argc - 1];
    // Reading in the file
    ifstream myfile(infilename);
    if(!myfile) 
    {
      cerr << "Couldn't open file " << infilename;
      return 1;
    }

    vector<Spaxel> whole_list;
    string line;
    while( getline(myfile, line) )
    {
      Spaxel data;
      stringstream linestr (line);
      linestr >> data;
      whole_list.push_back(data);

      cout << data << '\n';
    }
}

编辑:只是为了帮助澄清评论中的一些事情。

如您所知main,它是程序的入口点,因此它不是您自己的代码调用的东西。额外的可选参数int argc, const char *argv[]是当您使用参数运行程序时选项和参数的传递方式。第一个参数argc表示传入了多少个参数。第二个argv是一个数组,char *每个元素都是传递的参数。第一个参数argv[0]是你的程序名,所以argc总是>= 1

假设您sample从 shell 执行程序:

./sample sample.csv

然后argcargv具有以下内容:

argc = 2;
argv[0] = "sample"
argv[1] = "sample.csv"

所以const char *infilename = argv[argc - 1];获取传入的最后一个参数,该参数应该是要读入的文件名。

于 2013-06-12T21:16:29.307 回答
0

抱歉,我没有在 struct 中执行此操作,但我希望您能得到它并解决您的问题。

char separator;
    int value1;
    int value2;
    int value3;
    while (myfile >> value1)
    {
        // Skip the separator, e.g. comma (',')
        myfile >> separator;

        // Read in next value.
        myfile >> value2;

        // Skip the separator, e.g. comma (',')
        myfile >> separator;

        // Read in next value.
        myfile >> value3;

        // Ignore the newline, as it is still in the buffer.
        myfile.ignore(10000, '\n');

    }

上面的代码片段并不健壮,但演示了从文件中读取、跳过非数字分隔符和处理行尾的概念。代码也进行了优化。

于 2018-05-02T00:39:06.043 回答