循环遍历数据文件

时间:2016-04-23 15:16:21

标签: c while-loop cs50

我一直在研究哈佛CS50课程的问题集,我们的任务是从存储卡中恢复jpeg。该卡依次存储jpgs。在编写我的程序时,我决定使用while循环来循环直到EOF,但是使用课程中包含的调试器我发现我的循环永远不会启动。我在下面包含了我的代码,我真的希望有人可以帮我理解我在循环中出错的地方。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int main(int argc, char* argv[])
{
    // Ensure proper Usage
    if (argc != 1)
    {
        printf("This file takes no input commands!\n");
        return 1;
    }

    // open up card data file
    FILE* dataFile = fopen("card.raw", "r");
    if (dataFile == NULL) 
    {
        char* invalidFile = "card.raw";
        printf("Could not open %s.\n", invalidFile);
        return 2;
    }

    // Create variable to keep track of num of output files written
    int numFiles = 0;

    // Create buffer
    int* buffer = (int*)malloc(sizeof(int*) * 512);

    // Create new file conditions
    bool a = buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff;
    bool b = buffer[3] == 0xe0 || buffer[3] == 0xe1|| buffer[3] == 0xe2 || 
             buffer[3] == 0xe3 || buffer[3] == 0xe4 || buffer[3] == 0xe5 || 
             buffer[3] == 0xe6 || buffer[3] == 0xe7 || buffer[3] == 0xe8 || 
             buffer[3] == 0xe9 || buffer[3] == 0xea || buffer[3] == 0xeb || 
             buffer[3] == 0xec || buffer[3] == 0xed || buffer[3] == 0xee || 
             buffer[3] == 0xef;

    // Loop through until all files found         
    while(fread(&buffer, 512, 1, dataFile) == 1)
    {
        if(a && b)
        {
            // Create temporary storage
            char title[999];
            // print new file name
            sprintf(title, "%d.jpg", numFiles);
            // open new file
            FILE* img = fopen(&title[numFiles], "a");
            numFiles = numFiles + 1;
            fwrite(&buffer, sizeof(buffer), 1, img);
            free(buffer);
        }
        else 
        {
            if(numFiles > 0) 
            {

            }
        }
    } 
}

2 个答案:

答案 0 :(得分:2)

好吧,你可能有不止一个误解。

首先看一下fread手册页

  

成功时, fread() fwrite()会返回读取或写入的的数量。

因此,如果您请求 512 字节,则应该返回 512 。 如果它返回的更少,你知道:要么你到达了文件的末尾,要么出错了。

如果你指定:

bool a = something;
bool b = somethingElse;

然后:

while(somethingEntirelyElse) {
    // Never update the value of a or b
    if(a && b) { ... }
    // Neither here ...
}

然后你可以打电话给那个检查多余的不能吗?

除非ab实际上是易失性,否则就是这样。但不要去那里!

在您的情况下,ab的分配很可能属于 while循环。

然后你在循环之外分配你的buffer,但每次实际写下它时免费它。在下一次迭代中,您获得分段错误

您是否考虑过如果任何图像文件的大小超过512字节,并且图像未正确对齐,会发生什么?

更好的方法是保存一个文件的开头位置,一旦遇到EOF(你不是真的在寻找...),你就会知道文件的确切大小,并且你的缓冲区必须有多大。

总之,我同意一些评论者的观点,你们真的应该看一些早期的作业,看看你是否可以从中学到一些东西。

比喻时间:

假设您有一本书,并且您希望复制每个包含图像的页面。 你告诉自己:我只是遵循一个简单的算法,所以我可以考虑别的事情。

您的算法是:

  • 拥有影印机

  • 请在笔记本上记下网页是否包含图片。

  • 看一下(截至尚未完成的书)并查看是否有图像。 - &GT;在笔记本上记下结果

  • 只要 next 页面上只有一个字母,就开始翻页。 (不多也不少) - &gt;你在大多数情况下立即停止

  • 如果笔记本上写着:有图像,请复制此页面(请注意,笔记本将首次说明您在其上写的内容)

  • 如果您刚复制了一张图片,请丢弃您的复印机(并且不要为下一张图片购买新的复印机)

答案 1 :(得分:1)

在调用malloc之后,buffer指向已分配的内存(希望;您应该检查buffer != null),但该内存的内容未定义。然而,你使用它并将它与0xFF进行比较,这是毫无意义的。您首先必须从文件中读取数据。

文件通常由字节组成,而不是整数,因此您的缓冲区应为unsigned char *类型。