fopen更改C中的变量值
我正在参加哈佛大学的EDx CS50课程学习C,我注意到其中一个习题集中我的代码有一个奇怪的行为(我已经想出了一个可行的解决方案,但我想了解为什么原来的解决方案不可行)。分配的思想是检查一个文件,其中对jpeg文件的引用已被删除,从而从内存中恢复照片 我遇到的问题是下面的fopen更改C中的变量值,c,cs50,C,Cs50,我正在参加哈佛大学的EDx CS50课程学习C,我注意到其中一个习题集中我的代码有一个奇怪的行为(我已经想出了一个可行的解决方案,但我想了解为什么原来的解决方案不可行)。分配的思想是检查一个文件,其中对jpeg文件的引用已被删除,从而从内存中恢复照片 我遇到的问题是下面的foundJPEGboolean。我最初的想法是将其设置为false,直到找到第一张照片,然后开始写入各个文件(它们应该在连续的内存块中)。第一次找到jpeg头时,将生成一个新的写入文件,并将信息复制到其中,直到找到一个新的jp
foundJPEG
boolean。我最初的想法是将其设置为false,直到找到第一张照片,然后开始写入各个文件(它们应该在连续的内存块中)。第一次找到jpeg头时,将生成一个新的写入文件,并将信息复制到其中,直到找到一个新的jpeg。此外,foundJPEG
变量将变为true
。最初,我只在if(foundJPEG)
代码块的else子句下有这个声明,但运行它之后,我注意到每次调用fopen
函数时,变量都返回到false
。因此,我刚刚添加了一个新的foundJPEG=true打开新文件后的代码>语句,即使在变量已更改为true的情况下也是如此
我想知道的是为什么每次调用fopen
时布尔值都会变为false。特别是,由于C对内存分配提供了如此多的控制,我想知道这是否是因为每当我打开一个文件时,它都会以某种方式被覆盖,还是因为某些作用域问题。我想这可能是一个新手犯的错误,但我想也许有人可以帮助我更好地理解这一点,这样我在编写更大的应用程序时就不会犯复杂的错误。多谢各位
/*
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
typedef uint8_t BYTE;
int main(int argc, char* argv[]) {
int k = 0;
bool foundJPEG = false;
char title[7];
FILE* file = fopen("card.raw", "rb");
FILE* img;
BYTE buf[512];
int size = sizeof(buf);
while(fread(&buf, size, 1, file) == 1) {
if(buf[0] == 0xff && buf[1] == 0xd8 && buf[2] == 0xff && buf[3] >= 0xe0 && buf[3] <= 0xef) {
if(foundJPEG) {
fclose(img);
k++;
sprintf(title, "%03d.jpg", k);
img = fopen(title, "wb");
foundJPEG = true;
}
else {
sprintf(title, "%03d.jpg", k);
img = fopen(title, "wb");
foundJPEG = true;
}
}
if(foundJPEG) {
fwrite(&buf, size, 1, img);
}
}
fclose(img);
return 0;
}
/*
*恢复
*
*计算机科学50
*习题集4
*
*从法医图像恢复JPEG。
*/
#包括
#包括
#包括
#包括
typedef uint8_t字节;
int main(int argc,char*argv[]){
int k=0;
bool foundJPEG=false;
字符标题[7];
FILE*FILE=fopen(“card.raw”、“rb”);
文件*img;
字节buf[512];
int size=sizeof(buf);
while(fread(&buf,size,1,file)==1){
如果(buf[0]==0xff&&buf[1]==0xd8&&buf[2]==0xff&&buf[3]>=0xe0&&buf[3]代码中至少有两个未定义行为的实例
fclose(img);
您在img未初始化的情况下调用此
char title[7];
sprintf(title, "%03d.jpg", k);
sprintf将向7字节缓冲区写入8个字符的3+4+空终止符,这将覆盖堆栈上的其他内容
很可能是其中一个原因导致了你的问题。你能把你的问题压缩成一两句话吗?读小说不是很有趣。我认为你在第一次给fclose(img)打电话时可能有未定义的行为当img从未定义过时。另外,在if和else FOUNDPEG测试中有一块完全相同的代码。@对不起,这是我第一次在这里写问题。基本上,我想知道为什么在那块代码中fopen函数会更改FOUNDPEG布尔值。有什么原因会将uint8_t
混淆为BYTE
? 1)所有大写字母只能用于宏/枚举常量。2)一个字节不一定有8位。3)使用标准类型可以使代码对任何人都清晰,而不知道byte
的声明。4)typedef
仅用于将语义包含到名称中。@Olaf实际上不是这样,赋值的另一部分使用了它d我试图在自己的代码中使用它,以确保我理解它是如何工作的(字节与Microsoft网站中建议的位图infoheader结构有关)。无论如何,谢谢,jcoder已经指出了导致未定义行为的原因,所以我将继续阅读,以确保我不会再次犯此类新手错误:)。非常感谢!你是对的,我忘记了标题数组中的null终止符:(.关于img的事情,我猜我应该从现在开始将它们初始化为null。