我的终端在运行C程序后冻结

我的终端在运行C程序后冻结,c,cs50,C,Cs50,我想做什么 我试图解决CS50中的问题,它是这样的 你得到了一个不知怎么损坏的文件,怎么办?这个文件应该是多个JPG文件,而不是一个大文件。您的任务是将所述文件分为多个JPG,为此,您必须循环原始文件中的字节,并找到0xff 0xd8 0xff和一个介于0xe0和0xef之间的数字。。。这些数字意味着什么?它们表示JPG的开始,所以你必须根据这些信息创建和关闭文件 这个问题很长,所以请按了解更多 我做了什么 #包括 #包括 #包括 #包括 //创建新的数据类型BYTE typedef uint8

我想做什么

我试图解决CS50中的问题,它是这样的

你得到了一个不知怎么损坏的文件,怎么办?这个文件应该是多个JPG文件,而不是一个大文件。您的任务是将所述文件分为多个JPG,为此,您必须循环原始文件中的字节,并找到
0xff 0xd8 0xff
和一个介于
0xe0
0xef
之间的数字。。。这些数字意味着什么?它们表示JPG的开始,所以你必须根据这些信息创建和关闭文件

这个问题很长,所以请按了解更多

我做了什么

#包括
#包括
#包括
#包括
//创建新的数据类型BYTE
typedef uint8_t字节;
int main(int argc,char*argv[])
{
//变数
int计数器=0;
字符名[8];
//创建新的字节数组,它是512,因为正如您稍后看到的,我正在以512字节块读取输入文件
字节缓冲区[512];
int字节=512;
//输出图像
文件*img;
//输入图像
文件*f;
//检查传递的参数是否错误
如果(argc!=2)
{
printf(“用法:./recover”);
返回1;
}
//打开传入参数的文件
f=fopen(argv[1],“r”);
//检查文件是否为空
如果(f==NULL)
{
printf(“bruh”);
返回1;
}
//循环直到你到达零
//还从输入文件中读取512字节的数据块并存储到缓冲区
while(fread(缓冲区,字节,1,f))
{
//检查这是否是jpg,如果是,则检查它是否是第一个jpg
如果(缓冲区[0]==0xff&&buffer[1]==0xd8&&buffer[2]==0xff&&buffer[3]&0xf0)==0xe0&&counter==0)
{
//为名称指定新值
sprintf(名称为“%03i.jpg”,计数器);
//使用我们刚刚创建的名称创建新文件
img=fopen(名称,“w”);
//写入该文件
fwrite(缓冲区,字节,1,img);
//将文件数增加1
计数器++;
}
//检查它是否遇到另一个jpg,如果遇到,它将关闭最后创建的文件并创建一个新文件
否则如果(缓冲区[0]==0xff&&buffer[1]==0xd8&&buffer[2]==0xff&&buffer[3]&0xf0)==0xe0)
{
//关闭最后一个文件
fclose(img);
//根据打印的图像数量为名称指定新值
sprintf(名称为“%03i.jpg”,计数器);
//使用我们刚刚创建的名称创建新文件
img=fopen(名称,“w”);
//写入该文件
fwrite(缓冲区,字节,1,img);
//将文件数增加一个
计数器++;
}
//如果没有遇到JPG,则继续写入最后一个文件
其他的
{
fwrite(缓冲区,字节,1,img);
}
}
//关闭打开的文件
fclose(f);
fclose(img);
返回0;
}
如果你认为我在没有告诉你我做了什么的情况下向你扔了一大块代码,我已经把所有的都注释掉了

出了什么问题

根据文章的标题,当我运行程序并传递一些参数时。。。终端只是冻结,什么也没有出现。。。从来没有错误

如果要复制此问题,请执行以下操作:

  • 运行
    wgethttps://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip
    在您的终端中,解压缩文件

  • 然后键入
    makerecover
    进行编译(如果不起作用,只需使用
    叮当声(正常)

  • 最后键入
    /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
指向 对于任意但可到达的内存,它可能偶然解释 此未定义/未初始化的
文件
与标准相关 输入输出;然后在标准I/O上发送任意字节可以冻结 终端…

但是没有什么比这更不确定的了……

为什么不使用调试器来查看它被卡住的地方呢?@BinyaminR因为
debug50
做同样的事情,它会冻结,我必须重新启动一个新的终端窗口。我不知道什么是debug50,但调试器不会冻结。它允许您进入正在运行的程序,查看它“卡住”的位置。那么简单的printf呢?似乎还有很多调试您还没有完成。我不太相信这一点。要么您没有正确使用该工具,要么它已损坏,与您的程序无关。任何像样的调试器都允许您在程序启动之前收支平衡,而您的程序将无法影响这一点。那printf呢?
if(img!=NULL) // you forgot this test
{
  fwrite(buffer, bytes, 1, img);
}