fopen 更改 C 中的变量值
fopen changes variable value in C
我正在哈佛学习 EDx CS50 class 来学习 C,我注意到我的代码在其中一个问题集中有一个奇怪的行为(我已经想出了一个有效的解决方案,但我想了解为什么原来的没有)。任务的想法是检查一个文件,其中对 jpeg 文件的引用已被删除,从而从内存中恢复照片。
我遇到的问题是下面的 foundJPEG
布尔值。我最初的想法是将其设置为 false,直到找到第一张照片,然后开始写入各个文件(它们应该位于连续的内存块中)。第一次找到 jpeg header 时,将生成一个新的写入文件并将信息复制到那里,直到找到新的 jpeg。此外,foundJPEG
变量将变为 true
。最初我只在 if(foundJPEG)
代码块的 else 子句下有这个声明,但是在 运行 之后我注意到每次调用 fopen
函数时,变量都会返回 false
。因此,我只是在打开一个新文件后添加了一个新的 foundJPEG = true;
语句,即使在变量已经更改为 true 的情况下也是如此。
我想知道的是为什么每次调用 fopen
时布尔值都变为假。特别是,由于 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;
}
您的代码中至少有两个未定义行为实例。
fclose(img);
您正在使用未初始化的 img 进行调用
char title[7];
sprintf(title, "%03d.jpg", k);
sprintf 会将 8 个字符 3+4 + 空终止符写入 7 字节缓冲区,这将覆盖堆栈中的其他内容。
您的问题可能是其中一种原因造成的。
我正在哈佛学习 EDx CS50 class 来学习 C,我注意到我的代码在其中一个问题集中有一个奇怪的行为(我已经想出了一个有效的解决方案,但我想了解为什么原来的没有)。任务的想法是检查一个文件,其中对 jpeg 文件的引用已被删除,从而从内存中恢复照片。
我遇到的问题是下面的 foundJPEG
布尔值。我最初的想法是将其设置为 false,直到找到第一张照片,然后开始写入各个文件(它们应该位于连续的内存块中)。第一次找到 jpeg header 时,将生成一个新的写入文件并将信息复制到那里,直到找到新的 jpeg。此外,foundJPEG
变量将变为 true
。最初我只在 if(foundJPEG)
代码块的 else 子句下有这个声明,但是在 运行 之后我注意到每次调用 fopen
函数时,变量都会返回 false
。因此,我只是在打开一个新文件后添加了一个新的 foundJPEG = true;
语句,即使在变量已经更改为 true 的情况下也是如此。
我想知道的是为什么每次调用 fopen
时布尔值都变为假。特别是,由于 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;
}
您的代码中至少有两个未定义行为实例。
fclose(img);
您正在使用未初始化的 img 进行调用
char title[7];
sprintf(title, "%03d.jpg", k);
sprintf 会将 8 个字符 3+4 + 空终止符写入 7 字节缓冲区,这将覆盖堆栈中的其他内容。
您的问题可能是其中一种原因造成的。