fread返回与nmemb相同的数字,但已到达文件末尾

时间:2018-07-31 23:44:26

标签: c eof fread cs50

我正在解决CS50中的一个问题,尽管我不了解其中的测试行为,但我的代码还是成功的。 第63行if (feof(inptr))检查是否到达文件末尾,然后要求打印缓冲区指针的大小,该大小应小于初始化时的大小(512)。 尽管达到了EOF,它仍然返回512的值,这没有任何意义。

有人可以告诉我怎么了吗?

#include <stdio.h>
#include <string.h>


int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "Usage: copy infile outfile\n");
        return 1;
    }

    // remember filenames
    char *infile = argv[1];
    char *outfile = "000.jpg";

    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE *outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 3;
    }

    // declaring variable
    unsigned char buffer[512];
    int count = 0;
    int test = 512;

    // Execute until we find end of card
    while (!feof(inptr))
    {

        // Read buffer in card
        fread(buffer, 1, sizeof(buffer), inptr);

        // Checks for jpeg signature
        if (buffer[0] == 0xff &&
            buffer[1] == 0xd8 &&
            buffer[2] == 0xff &&
            (buffer[3] & 0xf0) == 0xe0)
        {
            fwrite(buffer, 1, sizeof(buffer), outptr);
            fread(buffer, 1, sizeof(buffer), inptr);

            // Checks if we are still in a jpeg, not the beginning of new one
            while (buffer[0] != 0xff ||
            buffer[1] != 0xd8 ||
            buffer[2] != 0xff ||
            (buffer[3] & 0xf0) != 0xe0)
            {
                // Exits loop if end of file
                if (feof(inptr))
                {
                    int size = sizeof(buffer);
                    printf("%i\n", size);
                    break;
                }

                fwrite(buffer, 1, sizeof(buffer), outptr);
                fread(buffer, 1, sizeof(buffer), inptr);

            }
            if (feof(inptr))
            {
                break;
            }

            // Close jpeg
            fclose(outptr);

            // Change count to apply to next jpeg title
            count++;

            char img_num[4];
            sprintf(img_num, "%03i.jpg", count);

            // Assign new title to new jpeg
            outfile = img_num;
            printf("%s\n", outfile);
            outptr = fopen(outfile, "w");

            // We will have to read again in the main loop, so rewind
            fseek(inptr, -512, SEEK_CUR);
        }


    }

    printf("%i\n", test);

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

2 个答案:

答案 0 :(得分:3)

sizeof(buffer)告诉您buffer有多大。它没有告诉您其中有什么内容—当前没有多少字节有效,也没有告诉您在最后一个fread中读取了多少字节。

知道读取fread个字节的正确方法是使用其返回值。您应该使用以下代码:

size_t BytesRead = fread(buffer, 1, sizeof(buffer), inptr);

如果在此语句之后BytesRead小于sizeof buffer,则fread不会读取您要求的所有字节。这表明出现了问题,这比是否设置了文件EOF标志更好。

答案 1 :(得分:0)

(sizeof) returns size in bytes of the object representation of type

https://en.cppreference.com/w/cpp/language/sizeof

由于您为buffer分配了512个字节,因此sizeof将返回512。保持什么缓冲区无关紧要,因为它不是长度检查。