-2

私はifstreamクラスを調べようとしており、ファイルを読み取るコードの下に書いていますTest.txt

「Test.txt」 - コンテンツ

This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five

書かれたコード:

#include <iostream>
#include <fstream>
#include <limits>

using namespace std;

int main()
{

    char buff[50];

    char ch;
    ifstream is("test.txt");
    if (!is)
    cout << "Unable to open " << endl;

    while(is)
    {
        ch=(char)is.get();
        if(ch != EOF)//If EOF is not checked then
        //EOF converted as a char is displyed as
        // last char of the file
        cout << ch;
        }


    cout << "\n\n###########\n\n";
    is.clear(); //clearing ios_base::eofbit which was set 
    //in previous action
    is.seekg(0,ios_base::beg); //Going back to start of File

   while(is)
   {

     is.get(buff,50,'\n');
     cout << buff ;
     cout << "\n--------------\n";
     is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
     //Flushing the is stream as '\n' was left by get fn
   }


  cout << "\n\n@@@@@@@@@@@@@@\n\n";
    is.clear();
    is.seekg(0,ios_base::beg);

    while(!is.eof())
    {
        is.getline(buff,50,'\n');
        cout << buff;
        cout << "\n--------------\n";
        //No need to flush the is stream as '\n' 
        //was extracted and discarded by getline
        }

    cout << "\n\n$$$$$$$$$$$$$$\n\n";
    is.clear();
    is.seekg(0,ios_base::end);
    int size=is.tellg();
    is.seekg(0,ios_base::beg);
    cout << "size : " << size << endl;

    //char* readBuff = (char *) ::operator new(sizeof(char)*size);
    char* readBuff = new char[size];
    is.read(readBuff,size);
    cout << readBuff;
    delete(readBuff);

    is.close();

    return 0;
    }

出力:

Gaurav@Gaurav-PC /cygdrive/d/Trial
$ ./Trial
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five

###########

This is Line One
--------------
This is Line Two
--------------
This is Line Three
--------------
This is Line Four
--------------
This is Line Five
--------------


@@@@@@@@@@@@@@

This is Line One
--------------
This is Line Two
--------------
This is Line Three
--------------
This is Line Four
--------------
This is Line Five
--------------


$$$$$$$$$$$$$$

size : 92
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five▒u

質問して明確にしたい問題がいくつかあります。

1)get以下のように使用する場合

   while(is)
   {

     is.get(buff,50,'\n');
     cout << buff ;
    // cout << "\n--------------\n";
     is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
     //Flushing the is stream as '\n' was left by get fn
   }

つまり、コメントアウトするcout << "\n--------------\n";と、ファイルは次のように読み取られます

###########

This is Line Fivee

つまり、最初の 4 行を見逃して、最後の 1 行だけ余分に読み取り'e'ます。

2)getline以下のように使用する場合:

// while(!is.eof())
   while(is)
    {
        is.getline(buff,50,'\n');
        cout << buff;
        cout << "\n--------------\n";
        //No need to flush the is stream as '\n'
        //was extracted and discarded by getline
        }

つまりwhile(is)、代わりに使用しましたwhile(!is.eof())-出力を得ました:

@@@@@@@@@@@@@@

This is Line One
--------------
This is Line Two
--------------
This is Line Three
--------------
This is Line Four
--------------
This is Line Five
--------------

--------------

つまり、最後の行の後に 2 行追加されます。もう一度理由を理解できませんか?

3)read関数92を使用すると、ファイル内の文字の総数が、および89を含むサイズが得られます。また、最後の行には、ファイルの最後の文字を育てた後に 2 つのゴミ文字が表示されます。なぜそのような行動?EOFspaces'\n'

cout << "\n\n$$$$$$$$$$$$$$\n\n";
is.clear();
is.seekg(0,ios_base::end);
int size=is.tellg();
is.seekg(0,ios_base::beg);
cout << "size : " << size << endl;

//char* readBuff = (char *) ::operator new(sizeof(char)*size);
char* readBuff = new char[size];
is.read(readBuff,size);
cout << readBuff;
delete(readBuff);

出力:

$$$$$$$$$$$$$$

size : 92
This is Line One
This is Line Two
This is Line Three
This is Line Four
This is Line Five▒u

ありがとう

編集:

Mats Peterson が受け取った回答ごとに、以下のコードを試しました。

while(is.get(buff,50,'\n'))
   {
     cout << buff ;
     //cout << "\n--------------\n";
     is.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
     //Flushing the is stream as '\n' was left by get fn
   }


  cout << "\n\n@@@@@@@@@@@@@@\n\n";
    is.clear();
    is.seekg(0,ios_base::beg);

   // while(!is.eof())
   while(is.getline(buff,50,'\n'))
    {

        cout << buff;
        //cout << "\n--------------\n";
        //No need to flush the is stream as '\n'
        //was extracted and discarded by getline
        }

しかし、出力を得ました:

###########

This is Line Fivee

@@@@@@@@@@@@@@

This is Line Fivee

つまり、最後の行のみが読み取られます...コメント//cout << "\n--------------\n";を外すと、適切な読み取りが得られます

@下票せめてコメントしてください。私はこの問題に直面したため、専門家からより多くの洞察を得るためにここに尋ねました..

4

2 に答える 2

0

eof を使用しているため、ガベージ値と呼ばれる余分な値または行を読み取る主な理由の 1 つ (私はそう思います)。たとえば、ファイルから文字を読み取るために使用した場合、その文字を読み取りますが、ファイルが終了しないだけでなくループもポイントで終了しないため、ファイルから余分な値を再度読み取ります。私が言いたい主なことは、入出力条件ではなく、ファイルの読み取りが終了するまでループステートメントで関数 eof を避けることです。

于 2013-10-16T07:03:49.070 に答える