4

値が 0、1、2、3、50、または 100 の 3 行 5 列の .csv ファイルがあります。Excel シートから .csv ファイルに保存しました。C++ を使用して .csv ファイルを読み込み、最後の 3 つの列の値に基づいて、.csv ファイルの最初の 2 つの列の値をテキスト ファイルに出力しようとしています。私は.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 で実行すると、3 つの 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は、渡された引数の数を示します。2 番目のパラメーターは、各要素が渡された引数でargvある の配列です。char *最初の引数argv[0]はプログラム名であり、argc常に>= 1.

sampleシェルからプログラムを実行するとします。

./サンプルサンプル.csv

次にargcargv次のようになります。

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

そのため、最後に渡された引数を取得します。これconst char *infilename = argv[argc - 1];は、読み込むファイル名である必要があります。

于 2013-06-12T21:16:29.307 に答える