我一直在研究哈佛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)
{
}
}
}
}
答案 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 ...
}
然后你可以打电话给那个检查多余的不能吗?
除非a
和b
实际上是易失性,否则就是这样。但不要去那里!
在您的情况下,a
和b
的分配很可能属于 while
循环。
然后你在循环之外分配你的buffer
,但每次实际写下它时免费它。在下一次迭代中,您将获得分段错误。
您是否考虑过如果任何图像文件的大小超过512字节,并且图像未正确对齐,会发生什么?
更好的方法是保存一个文件的开头位置,一旦遇到EOF(你不是真的在寻找...),你就会知道文件的确切大小,并且你的缓冲区必须有多大。
总之,我同意一些评论者的观点,你们真的应该看一些早期的作业,看看你是否可以从中学到一些东西。
比喻时间:
假设您有一本书,并且您希望复制每个包含图像的页面。 你告诉自己:我只是遵循一个简单的算法,所以我可以考虑别的事情。
您的算法是:
拥有影印机
请在笔记本上记下网页是否包含图片。
看一下(截至尚未完成的书)并查看是否有图像。 - &GT;在笔记本上记下结果
只要 next 页面上只有一个字母,就开始翻页。 (不多也不少) - &gt;你在大多数情况下立即停止
如果笔记本上写着:有图像,请复制此页面(请注意,笔记本将首次说明您在其上写的内容)
如果您刚复制了一张图片,请丢弃您的复印机(并且不要为下一张图片购买新的复印机)
答案 1 :(得分:1)
在调用malloc
之后,buffer
指向已分配的内存(希望;您应该检查buffer != null
),但该内存的内容未定义。然而,你使用它并将它与0xFF
进行比较,这是毫无意义的。您首先必须从文件中读取数据。
文件通常由字节组成,而不是整数,因此您的缓冲区应为unsigned char *
类型。