2016-11-11 17 views
1

私は整数の行を持つファイルを持っています。私は配列内のスロットに各行を読み込みたい。私は以下のコードを持っていますが、動作しません。私は正しい道にいるかどうか分からない。ファイルからデータを読み込み、各行を配列に格納していますか?

void Read_Save() { 
    ifstream in; 
    int arr[100]; 
    string line; 
    in.open("file.txt"); 
    while (in.peek() != EOF) 
    { 
     getline(in, line, '\n'); 
     strcpy(arr, line.c_str()); 
    } 
    in.clear(); in.close(); 
} 
+2

あなたはstrcpy' – Raindrop7

+2

'と入力する整数の配列を'ながら(!in.peek()= EOF) '動作しますができませんが、とEOFトラップを読む前にEOFのテストに陥っていないといいですが、 'while(getline(in、line、 '\ n'))'は 'peek'を保存し、ただEOF。 – user4581301

答えて

2

文字列から整数値を解析する方法はいくつかあります。

まずは、あなたのループを修正してみましょう。ここでは

int pos = 0; 
while(std::getline(in, line) && pos < 100) 
{ 
    int value = 0; 

    // Insert chosen parsing method here 

    arr[pos++] = value; 
} 

は、一般的なオプションの非網羅的なリストである:

  1. 使用std::strtol

    // Will return 0 on error (indistinguishable from parsing actual 0) 
    value = std::strtol(line.c_str(), nullptr, 10 ); 
    
  2. 使用std::stoi

    // Will throw exception on error 
    value = std::stoi(line); 
    
  3. std::istringstreamを構築し、そこから読み:

    std::istringstream iss(line); 
    iss >> value; 
    if(!iss) { 
        // Failed to parse value. 
    } 
    
  4. 使用std::sscanf

    if(1 != std::sscanf(line.c_str(), "%d", &value)) 
    { 
        // Failed to parse value. 
    } 
    

pos < 100をチェックするループに境界テストの点に注意してください。これは、配列にストレージの制限があるためです。実際には、グローバルなものもRead_Saveにローカルなものでオーバーライドしています。したがって、関数の終了時に失われる小さな配列で隠してしまいます。

標準ライブラリが提供する他のコンテナタイプを使用して、任意のサイズの「配列」(実際には配列ではありません)を持つことができます。ランダムアクセスを提供する有用なものは、std::vectorおよびstd::dequeです。

std::vector<int> Read_Save(std::istream & in) 
{ 
    std::vector<int> values; 
    std::string line; 

    for(int line_number = 1; getline(in, line); line_number++) 
    { 
     try { 
      int value = std::stoi(line); 
      values.push_back(value); 
     } 
     catch(std::bad_alloc & e) 
     { 
      std::cerr << "Error (line " << line_number << "): Out of memory!" << std::endl; 
      throw e; 
     } 
     catch(std::exception & e) 
     { 
      std::cerr << "Error (line " << line_number << "): " << e.what() << std::endl; 
     } 
    } 

    return values; 
} 

そして最後に、呼び出しは次のようになります:のは、ベクターを使用して、もう少し有用であることがRead_Saveの定義を変更してみましょう

std::ifstream in("file.txt"); 
std::vector<int> values = Read_Save(in); 
0

std::vectorを使用することをお勧めします。コードは次のようになります。

void Read_Save() 
{ 
    std::ifstream in("file.txt"); 
    int value; 
    std::vector<int> arr; 

    while (in >> value) 
     arr.push_back(value); 

    for(int i(0); i < arr.size(); i++) 
     std::cout << arr[i] << ", "; 

    std::cout << std::endl; 
    in.close(); 
} 
+1

また、イテレータとして 'std :: copy()'と 'std :: istream_iterator'と' std :: back_inserter'を使用して手動whileループを置き換えることもできます: 'std :: copy(std :: copy() istream_iterator (in)、std :: istream_iterator()、std :: back_inserter(arr)); ' –

1

あなたは文字列を整数に変換するにはstrcpy()を使用することはできません。あなたはstd::strtol()またはstd::stoi()、あるいはstd::istringstream、例えば使用することができます。

int arr[1000]; 

void Read_Save() { 
    ifstream in; 
    string line; 
    in.open("file.txt"); 
    int index = 0; 
    while ((index < 1000) && (getline(in, line))) 
    { 
     if (istringstream(line) >> arr[index]) 
      ++index; 
    } 
} 
+0

私はあなたのやり方が好きです。エラー\t C2027 \t未定義の型 'std :: basic_istringstream 、std :: allocator Jaden

+1

istringstreamのインクルードを追加しましたか?私は '#include ' – drescherjm

関連する問題