c - 我的终端在运行 C 程序后冻结
问题描述
我想做什么?
我正在尝试解决CS50 中的恢复问题,它是这样的......
你得到了一个以某种方式损坏的文件,怎么办?好吧,该文件应该是多个 JPG 文件,而不是一个大文件。您的任务是将所述文件分成多个 JPG,为此,您必须遍历原始文件中的字节并找到这个0xff 0xd8 0xff
和一个介于0xe0
和之间0xef
的数字……这些数字是什么意思?好吧,它们表示 JPG 的开始,因此您必须根据该信息创建和关闭文件...
这个问题很长,所以请按此了解更多信息。
我做了什么?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <cs50.h>
//create new data type BYTE
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
//variables
int counter = 0;
char name[8];
//create new array of BYTES, it is 512 because as you can see later I am reading the input file in 512 byte chunks
BYTE buffer[512];
int bytes = 512;
//output image
FILE* img;
//input image
FILE* f;
//checks if the arguments passed are wrong
if (argc != 2)
{
printf("Usage: ./recover <file>");
return 1;
}
//opens the file passed in the arguments
f = fopen(argv[1], "r");
//checks if file is null
if (f == NULL)
{
printf("bruh");
return 1;
}
//loop till you reach zero
//also read in 512 bytes chunks from the input file and store to buffer
while (fread(buffer, bytes, 1, f))
{
//checks if this is a jpg, and if it is checks if it is the first one
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0 && counter == 0)
{
//assigns new value to name
sprintf(name, "%03i.jpg", counter);
//creates new file with the name we've just created
img = fopen(name, "w");
//write to that file
fwrite(buffer, bytes, 1, img);
//increment number of files by 1
counter++;
}
//checks if it encoutered another jpg, if it did it will close the last created file and create a new one
else if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
//closes last file
fclose(img);
//assigns new value to name depending on how many images were printed
sprintf(name, "%03i.jpg", counter);
//creates new file with the name we've just created
img = fopen(name, "w");
//writes to that file
fwrite(buffer, bytes, 1, img);
//increment number of files by one
counter++;
}
//if no jpgs are encountered, continue to write to the last file
else
{
fwrite(buffer, bytes, 1, img);
}
}
//close opened files
fclose(f);
fclose(img);
return 0;
}
如果您认为我在没有告诉您我做了什么的情况下向您倾倒了一大段代码,那么我已经注释掉了每一位。
出了什么问题?
好吧,根据帖子的标题,当我运行程序并传递一些参数时……终端只是冻结了,什么也没有出现……没有任何错误。
如果你想复制这个问题:
wget https://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip
在您的终端中运行并解压缩文件...然后输入
make recover
编译(如果这不起作用,只需
正常使用clang)最后键入
./recover card.raw
运行程序...它应该产生大约 50 个文件,但它又没有
解决方案
else
即使之前没有找到合适的标题,您的最后一个也可能发生;在这种情况下,您的img
文件可能在使用之前尚未打开。
您必须首先正确初始化
FILE* img=NULL; // you forgot this initialisation
然后,在最后else
,您可以测试文件是否实际打开。
if(img!=NULL) // you forgot this test
{
fwrite(buffer, bytes, 1, img);
}
在我的计算机上,您的初始程序只是在分段违规时停止,因为碰巧,即使没有明确初始化,也
img
恰好是NULL
.
我猜如果fwrite()
使用未初始化的img
指向任意但可访问的内存,它可能会偶然将此未定义/未初始化的解释FILE
为与标准 I/O 相关;然后在标准 I/O 上发送任意字节可以冻结终端......
但没有什么是不确定的......
推荐阅读
- c# - 将 Power BI 嵌入 Windows 窗体应用程序 (.NET Framework)
- php - PDO 异常“找不到驱动程序”错误
- php - 如何在 Lumen 的路由中为 xml 文件添加扩展名
- .net-core - 不支持关键字:“初始目录”
- ruby - 在 Ruby / Capybara 测试套件中使用 selenium/standalone-chrome docker 映像
- unicode - Unicode 集符号的含义?
- spring-boot - 在运行一段未知的时间后,Spring 数据休息基本路径正在失去它的 @RepositoryRestResource 链接
- reactjs - 如何在 ReactJS 中创建 JSON 结构
- html - 我怎样才能得到一个漂浮在另外两个之上s 如果空间太窄,三个人都不能并排?
- python - 合并没有唯一键的数据框