2016-10-10 9 views
0

ファイルから読み込み、宿題のコマンドライン引数からデータを解析する作業をしています。私は壁にぶつかり、何が問題なのか分からず、私が逃していることについていくつかアドバイスを受けることができればと願っています。ファイルから読み込むと予期しない出力が発生する

データファイルはこのように構成されています。最初の行には、合計行数があります。それ以降の各行については、|で区切られた文字列です。キャラクター。私は '|'文字列を部分文字列に分割したいからです。

入力ファイルの例を示します。

3 
league of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

ここは私のコードです。

int main(int argc, char* const argv[]) 
{ 

//change string to char* so I can check through each char to see if the 
//thing I read in is '|' character. 
String Data = (argv[1]); 
ifstream fin (Data.c_str()); 

//check whether the file is open. 
if (!fin.is_open()) 
{ 
    cout << "Could not open file" << endl; 
} 

else 
{ 
    int dataLines; 
    char dataBuffer[100]; 

    //The first integer I read in will be how many lines I will loop through 
    fin >> dataLines; 
    //ignore the new line character and do not include it in the count of 
    //dataLines. 
    fin.ignore(); 

    //use noskipws so I can recognize whitespaces. 
    fin >> noskipws >> dataBuffer; 

    //TEST CODE: COMMENTED OUT FOR NOW. 
    //cout<<dataBuffer<<endl; 

    //loop for the number of lines 
    for(int i = 0; i < dataLines; i++) 
    { 

     fin.getline(dataBuffer, 100); 
     //print the buffer for checking 
     cout<<dataBuffer<<endl; 
    } 
} 
//close the file. 
fin.close(); 
return 0; 

}

結果はこのように見えることになっています。

league of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

実際の結果は、バッファがなくなってから私が読んで、この

of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

最初の単語のように見えます。 「リーグ」は欠けているもので、テストコードを自分のコードで指定された場所に挿入することで問題を確認しようとしました。与えられたテストコードでは、私の出力は

league 
of legends|Teemo|Master Yi|Vayne 
apple|samsung|smart phone|smart watch 
overwatch|d.va|junkrat|Reinhart 

あるので問題は間noskipwsとデータラインをループforloopでファイルを読み込むことです。前の私のバッファーはリーグです。しかし、ループに入るとすぐに、それは渡され、のすぐにになります。

私はここで何が欠けていますか?考えられる解決策は何でしょうか?

fin >> noskipws >> dataBuffer; 

はRHEL 7.1

答えて

0

は、次の行を必要としません。 1. >> noskipwsは、自動的に空白をスキップします.OPがストリームをどのように読み込んでいるかによって不要になります。 2. >> dataBufferはストリームから最初の単語を読み込みます。この場合は "league"という単語を使用します。

解決方法:これを行わないでください。

その他の問題:

fin.ignore(); 

は、1つの文字を無視します。しかし、誰かがカウントの後に目に見えないスペースを残したらどうなるでしょうか?代わりに、残りの行が完全に消費されるように、

fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

を使用してください。

char dataBuffer[100]; 

なぜ自分が苦しんでいるのですか? '|' 上に線をトークン化する

使用std::stringstreamstd::getline:代わりに

std::string dataBuffer; 

勧告を使います

std::stringstream stream(databuffer); 
std::string token; 
while (std::getline(stream, token, '|') 
{ 
    std::cout << token << ','; 
} 
+1

正しい。しかし、理由を説明するのに本当に便利です。 – user4581301

1

にG ++ 4.8.3 2の主な問題をテスト済み:

fin >> noskipws >> dataBuffer; 

は、2つのことを行い

+0

ありがとうございました!私はnoskipwsを取り除き、問題は解決されます。私は上に移動することができます! –

+0

またwhile(getline(stream、token、 '| "))ループは、データを' | 'で区切ります。私がやっていたことよりもはるかに短く、理解しやすいです。 –

0

ありがとうユーザー4581301データを正しく読み込み、 '|'で分割します。キャラクター。今私はクラスにデータを格納するために働くことができます。

同じ問題が発生している可能性のある人は、これが修正版のコードです。

int main(int argc, char* const argv[]) 
{ 

String Data = (argv[1]); 
ifstream fin (Data.c_str()); 

if (!fin.is_open()) 
{ 
    cout << "Could not open file" << endl; 
} 

else 
{ 
    int dataLines; 
    char dataBuffer[100]; 

    fin >> dataLines; 
    fin.ignore(); 

    for(int i = 0; i < dataLines; i++) 
    { 
     while(fin.getline(dataBuffer, 100, '|')) 
     { 
      cout<<dataBuffer<<endl;// check to see if it reads in correctly. 
     } 
    } 
} 
fin.close(); 
return 0; 
} 
関連する問題