1

次の C++ コードに off-by-one エラーがあり、それを理解できません。誰でも助けてください。コードとその出力を以下に示します。一番。

double* alloc_Array=new double[m_int_NumChann*m_int_NumSamples];
int int_SizeArray=int(0);
std::ifstream File;
File.open(m_char_Address);
if(File.is_open()){
    std::cout<<"input file opened...\n";
    int i=int(0);
    do{
        File>>alloc_Array[i];
        i++;
    }while(!File.eof());
    int_SizeArray=i;
}else{
    std::cerr<<"ERROR: input file can't be opened.\n";
    system("pause");
}
File.close();
if((m_int_NumChann*m_int_NumSamples)!=int_SizeArray){
    std::cerr<<"WARNING: number of samples multiplied by number of channels is not equal to total data points in the input file:\n";
    std::cerr<<"       number of samples in each channel = "<<m_int_NumSamples<<'\n';
    std::cerr<<"       number of channels = "<<m_int_NumChann<<'\n';
    std::cerr<<"       total data points by multiplication = "<<m_int_NumSamples*m_int_NumChann<<'\n';
    std::cerr<<"       number of data points in the input file = "<<int_SizeArray<<'\n';
    system("pause");
}

出力:

   input file opened...

   WARNING: number of samples multiplied by number of channels is not equal to tota
   l data points in the input file:

   number of samples in each channel = 77824

   number of channels = 11

   total data points by multiplication = 856064

   number of data points in the input file = 856065

   Press any key to continue . . .
4

2 に答える 2

3

これを修正する最も簡単な方法は、ループしないことeof()です。

eof()ループまたはgood()正しくループしようとすると、よく知られている問題があります。例については、次の質問を参照してください。stream.good() または !stream.eof()をテストすると、最後の行が 2 回読み取られます

i値が正常に読み取られた場合にのみインクリメントされるように、コードを並べ替えることができます。

int i=int(0);
while (File >> alloc_Array[i]) {
    i++;
}
int_SizeArray=i;
于 2014-07-22T16:10:57.357 に答える
2

do{} while() ループでは、毎回 i をインクリメントしています。長さゼロのファイルの場合を考えてみましょう。ループの最初のパスが発生し、その後 i は 1 になります。EOF にすぐに到達するため、それ以降のパスは発生しません。ただし、その場合、実際にはサンプルは見つかりませんでした。

ループの終了後、i を 1 回デクリメントする必要があります。ここで、見つかったサンプル数 (ループの実行回数より 1 少ない数) のカウントと、入力しようとした配列内の要素の数の違いに注意してください。

于 2014-07-22T15:17:43.897 に答える