2011-12-26 9 views
0

getlineを使用して、入力ファイルからバッファ内の文字をフェッチしています。行を読み終えたら、すべての文字をループし、マップ上でルックアップを行います(それ以上の操作については)。 問題は、有効な文字が終わると、私のプログラムは入力ストリームからeofを取り出し、マップ内でそれを探すことです。Getlineの文字バッファからEOFを分離する

私は、ストリームの終わりに達したときに表示するために、inputStream.eof()またはeofbitをチェックしてみましたが、問題は、これらの両方が、すぐに私は最終的getline()を作るように設定してしまうことがありますので、私は判断するためにそれを使用することはできませんここで、EOF文字は入力バッファにあります。

入力バッファ内のEOF文字を識別し、マップ内でそれを探すのを避けるにはどうすればよいですか?

while(fileInput) { 
fileInput.getline(charBuf,charBufSize); 

    for(int i=0; i<=charBufSize ;i++) { 
    char* currentChar = &(charBuf[i]); 
    // do something with currentChar, 
    // which I proceed to do by dereferencing currentChar when I need to access 
    // the actual character. 
    } 
} 
+0

@post some code –

+1

あなたが持っている問題を示すいくつかのコードを投稿することを怠ったようです。 –

+0

私がコードを投稿すると、なぜ、あまりにも多くのコードを投稿したのですか?それ以外の方法はありません:) – angryInsomniac

答えて

2

を使用しています。あなたがしなければならないことは、読み込まれた文字数のカウントを取得し、それを使ってファイルがどこで終了したかを知ることです。このカウントはistream::gcount()を使用して取得できます。

コードにいくつかの問題があります。

私はあなたが最初の問題は、あなたが入力の最初の行を破棄しているということです

char charBuf[256]; 
size_t charBufSize = 256; 
  1. 宣言したと仮定します。ファイルからの読み取りのための通常のイディオム、行ずつは、次のとおりです。

    while(fileInput.getLine(charBuf, charBufSize)) { 
        for (...) { // your for loop is wrong, but I'll get to that in a second 
        } 
    } 
    

    あなたは本当にあなたがループを開始する前に、最初の行を破棄したい場合は、

    fileInput.getLine(charBuf, charBufSize); // this first line will be ignored 
    while(fileInput.getLine(charBuf, charBufSize)) { 
        for (...) {  // your for loop is wrong, but I'll get to that in a second 
        } 
    } 
    
  2. を使用charBufSizeは最大量が含まれています実際に読み取られるデータの量ではなく、読み取ることができるデータの量。たとえば、12文字しか読み込めない場合は、キャラクタ13でマップルックアップを実行するだけでなく、14から256の文字を処理しようとします。これを避けるには、ループを

    に変更します
    for (int i=0; i < fileInput.gcount(); ++i) { 
        char* currentChar = &(charBuf[i]); 
        // do something with currentChar, 
        // which I proceed to do by dereferencing currentChar when I need to access 
        // the actual character. 
    } 
    
  3. <の代わりに<=を使用しています。私は上記のコードサンプルでこれを修正しました。

  4. 全部char* currentChar = &(charBuf[i]);物は少し珍しいです。あなたの質問から編集したコードでは(あなたが求めている基本的な入力質問がもっとはっきりしている)、それを正しく使っているようですが、簡単に宣言したように思われます。char currentChar = charBuf[i];マイナーあなたがそれを使用する1つの場所でcurrentCharを逆参照することを避けるために変更されています。

+0

信頼度の高い投票と有益な答えをありがとう:) 有効な文字がすべて終わった後にループが失敗した理由を理解できました。なぜならバッファサイズの最後までループしていたためです。今はgcount()を使って問題を解決しているようです(<、これはちょっとばかげた間違いでした) しかし、私のループは入力の最初の行を無視すると言いました。場合は、私はそれを介して、デバッガですべての文字が処理された、あなたはこれを詳しく教えてくださいできますか? – angryInsomniac

+0

@angryInsomniac:ループのすぐ上の 'getline'コマンドは、ファイルの最初の行を読み込みますが、それを処理しません。次に、ループに入り、 'getline'をもう一度呼び出して、ファイルの2行目を読み込み、そこで処理を開始します。 –

+0

私はコードをコピーする間にいくつかのエラーがあったと思います:D実際のコードには1つのgetlineしかありません。 – angryInsomniac

2

charBufには「EOF文字」はありません。 EOF文字がコンセプト(MS-DOSやWindowsなど)として存在するシステムでも、istream :: getline()はcharBufに格納しません。

投稿コードで1つの明らかな誤りがあるアウトオブバウンドループでのアクセス:i<=charBufSizei<charBufSizeする必要があります、しかし、あなたはどのように多くを見つけるためにfileInput.gcount()を使用する必要があるのIStream :: getlineのによって得られた文字だけを処理するために文字は、実際にcharbufにに書き込まれた:

// assuming char charBuf[charBufSize]; 
fileInput.getline(charBuf, charBufSize); 
for(int i=0; i<fileInput.gcount()-1; i++) // -1 if you don't want to process '\0' 
{ 

か、単にC++にはEOF文字はあなたがチェックできるということはありません文字列

// assuming std::string charBuf; 
getline(fileInput, charBuf); 
for(int i=0; i<charBuf.size(); i++) 
{ 
0

あなたはライン・バイ・ラインを読みたい場合は、標準のgetlineの慣用句を使用:あなたは、フォーマットされていない(「バイナリ」)入力を読み込む使用する代わりに、場合

std::string line; 
while (std::getline(inputFile, line)) 
{ 
    // process line 
} 

readgcount

std::array<char, 4096> buf; 
std::streamsize n; 
while (true) 
{ 
    inputFile.read(buf.data(), buf.size()); 

    if ((n = inputFile.gcount()) == 0) { break; } 

    // process [buf, buf + n) 
} 
関連する問題