开发者

File I/O logic with a while statement, how would this code be expected to behave?

I'm trying to understand some differences in file i/o techniques. Suppose I have the following code:

FILE *work_fp;
char record[500] = {0};
while(!feof(work_fp))
{
    static int first = 1;
    fgets(record, 200, work_fp);

    if (first)
    {
        var1 = 2;
        length += var1;
    }
    first = 0;

    if (feof(work_fp))
    {
        continue;
    }
    开发者_JAVA技巧if((int)strlen(record) < length)
    {
        fclose(work_fp);
        std::ostringstream err;
        err << "ERROR -> Found a record with fewer bytes than required in file."
            << std::endl;
        throw std::runtime_error(err.str());
    }
    const int var2 = 1;
    if(memcmp(argv[1], record + var2, 3) == 0)
    {
        load_count_struct(record, var1);
    }
}

I'm not seeing how the second if argument can be true.

if (feof(work_fp))
{
    continue;
}

If feof(work_fp) is true wouldn't the while argument be false? Then the continue could never get called?

FOLLOW UP QUESTION:

Ok, I see how fgets can cause work_fp to reach eof conditions.

Suppose I want to try and implement this another way. Using getline(), for example.

std::string data(file);
std::ifstream in(data.c_str());

if (!in.is_open())
{
    std::ostringstream err;
    err << "Cannot open file: " << file << std::endl;
    throw std::runtime_error(err.str());
}

std::string buffer = "";
std::string record = "";
while (getline(in, buffer))
{
    static int first = 1;

    if (first)
    {
        var1 = 2;
        length += var1;
    }
    first = 0;

    if (//What should go here?!?)
    {
        break;
    }
    // etc...
}

Any suggestions? I'm thinking

if (buffer == std::string::npos)

no?


The line:

fgets(record, 200, work_fp);

can advance to read/write head to the end of the file, thus changing the return value on feof.


First of all, your code invokes undefined behaviour, because you've not initialized work_fp, yet you're using it, passing it to feof(), first in while(!feof(work_fp)) , and elsewhere in the code.


Anyway, supposing you initialize it by opening some file, then I would answer your question as follows:

The following code reads some data from the file using work_fp, that means, it is possible that feof(work_fp) will return true in the second if condition, because after reading data using fgets(), the file pointer work_fp may reach end of file.

fgets(record, 200, work_fp);


In the while loop fgets() is called and the file pointer is advanced. Then if(feof(work_fp)) checks if the end of the file is reached. If so then continue the while loop. The while loop then continues if the end of the file is NOT reached, which in this case will be false. Hence the logic works.


That is a weird statement, and I think it should be

if (feof(work_fp)){
    break;
}

The continue; can get called, since it occurs after an fgets, but calling continue is pointless since that brings execution to the next iteration of the loop which is guaranteed to be false and quit the loop. It makes more sense, and is more readable/understable to put break; there.


Since you have a fgets within the while before your check on feof, the feof status of work_fp may have changed during that read, in which case, it may evaluate to true.


There is a read operation on work_fp between the while and if conditions, so that feof() could be true.


The eof can have been reached at the following line:

 fgets(record, 200, work_fp);

So right after having been evaluated to false in the while statement.

This would make the

 if (feof(work_fp))

evaluated to true. But this code can be simplified.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜