0

ここで私が間違っていることを教えてください。私がやりたいことはこれです:
1。4つの数字とこの数字のそれぞれが15桁のtxtファイルを持っています:

std::ifstream file("numbers.txt",std::ios::binary);

これらの数値を配列に読み込もうとしています。

  char num[4][15];

そして、私がやっていることは、ファイルの終わりに達しない限り、すべての行(最大15文字、「\ n」で終わる)をnum[lines]に書き込むことです。しかし、これはやや機能しません。まず、最初の数字だけが正しく読み取られ、残りは「」(空の文字列)であり、次にfile.eof()も正しく機能していないようです。このコードの下に表示しているtxtファイルでは、156行に達しました。何が起こっているのでしょうか。

                for (unsigned lines = 0; !file.eof(); ++lines)
                {
                    file.getline(num[lines],15,'\n');  
                }

したがって、「ルーチン」全体は次のようになります。

int main()
{
std::ifstream file("numbers.txt",std::ios::binary);

char numbers[4][15];

            for (unsigned lines = 0; !file.eof(); ++lines)
            {
                file.getline(numbers[lines],15,'\n');// sizeof(numbers[0])
            }
}

これは私のtxtファイルの内容です:

111111111111111
222222222222222
333333333333333
444444444444444

PS
私はVS2010sp1を使用しています

4

5 に答える 5

6

eof() 関数を使用しないでください! 行を読み取る標準的な方法は次のとおりです。

while( getline( cin, line ) ) {
    // do something with line
}
于 2011-06-08T18:01:24.450 に答える
1

file.getline()14 文字を抽出し、num[0][0] .. num[0][13]. 次に、バッファがいっぱいで終了文字に達していないときに行うことなので、 '\0'inを格納してonnum[0][14]を設定します。failbitfile

failbit が設定されているため、さらに呼び出しを試みてfile.getline()も何もしません。

eofbit が設定されていないため、テストは trueを!file.eof()返します。

編集:実際の例を示すには、もちろん文字列を使用するのが最善ですが、char配列を埋めるには、次のようにすることができます:

#include <iostream>
#include <fstream>
int main()
{
    std::ifstream file("numbers.txt"); // not binary!
    char numbers[4][16]={}; // 16 to fit 15 chars and the '\0'
    for (unsigned lines = 0;
         lines < 4 && file.getline(numbers[lines], 16);
         ++lines)
    {
        std::cout << "numbers[" << lines << "] = " << numbers[lines] << '\n';
    }
}

Visual Studio 2010 SP1 でテスト済み

于 2011-06-08T18:01:38.263 に答える
1

ifstream docによると、読み取りは n-1 文字が読み取られるか delim 記号が見つかった後に停止します。最初の読み取りには 14 バイトしかかかりません。

それはバイトを読み取ります: '1' (文字) は 0x41 です: あなたが期待するように、バッファは 1 ではなく 0x41 で満たされ、最後の文字は 0 になります (c-string の終わり)

補足として、コードは、行が配列を超えていないことを確認しません。

getline を使用すると、テキストを期待していて、ファイルをバイナリモードで開くと想定されます。私には間違っているようです。

于 2011-06-08T18:05:01.600 に答える
0

次のように変更します。

#include <cstring>

int main()
{
    //no need to use std::ios_base::binary since it's ASCII data
    std::ifstream file("numbers.txt");

    //allocate one more position in array for the NULL terminator
    char numbers[4][16];

    //you only have 4 lines, so don't use EOF since that will cause an extra read
    //which will then cause and extra loop, causing undefined behavior
    for (unsigned lines = 0; lines < 4; ++lines)
    {
        //copy into your buffer that also includes space for a terminating null
        //placing in if-statement checks for the failbit of ifstream
        if (!file.getline(numbers[lines], 16,'\n'))
        {
            //make sure to place a terminating NULL in empty string
            //since the read failed
            numbers[lines][0] = '\0';
        }
    }

}
于 2011-06-08T18:01:28.837 に答える
0

最初の like の最後にある '\n' は考慮されておらず、バッファに残っているようです。したがって、次にgetline()読み取られます。

各 getline() の後に file.get() を追加してみてください。

1 つの file.get() が機能しない場合は、2 つ試してみてください。これは、Windows の既定のファイル エンコーディングでは、行が '\n\r\' (または '\r\n'、わかりません :) で終わるためです。

于 2011-06-08T18:02:10.417 に答える