运行 C 程序后我的终端死机了
My terminal freezes after running C program
我想做什么?
我正在尝试解决 CS50 中的 recover 问题,它是这样的...
你得到了一个损坏的文件,怎么办?那么该文件应该是多个 JPG 文件而不是一个大文件。你的任务是将所述文件分成多个 JPG,为此你必须遍历原始文件中的字节并找到这个 0xff 0xd8 0xff
和一个介于 0xe0
和 0xef
之间的数字...这些数字是什么意思?好吧,它们表示 JPG 的开始,因此您必须根据该信息创建和关闭文件...
问题很长,请按this了解更多。
我做了什么?
#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;
}
如果你认为我在没有告诉你我做了什么的情况下把一大块代码扔给了你,我已经注释掉了每一点。
出了什么问题?
好吧,根据 post 的标题,当我 运行 程序并传递一些参数时......终端只是冻结,什么也没有出现......从来没有错误。
如果你想重现这个问题:
运行 wget https://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip
在您的终端中解压文件...
然后键入 make recover
进行编译(如果这不起作用,请使用
正常响)
最后输入 ./recover card.raw
到 运行 程序...它应该产生大约 50 个文件,但它又没有
即使没有合适的 header,您的最后一个 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
指向
到任意但可访问的内存,它可以偶然解释
这 undefined/uninitialised FILE
与标准相关
I/O;然后在标准 I/O 上发送任意字节可以冻结
终端...
但没有什么是不确定的...
我想做什么?
我正在尝试解决 CS50 中的 recover 问题,它是这样的...
你得到了一个损坏的文件,怎么办?那么该文件应该是多个 JPG 文件而不是一个大文件。你的任务是将所述文件分成多个 JPG,为此你必须遍历原始文件中的字节并找到这个 0xff 0xd8 0xff
和一个介于 0xe0
和 0xef
之间的数字...这些数字是什么意思?好吧,它们表示 JPG 的开始,因此您必须根据该信息创建和关闭文件...
问题很长,请按this了解更多。
我做了什么?
#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;
}
如果你认为我在没有告诉你我做了什么的情况下把一大块代码扔给了你,我已经注释掉了每一点。
出了什么问题?
好吧,根据 post 的标题,当我 运行 程序并传递一些参数时......终端只是冻结,什么也没有出现......从来没有错误。
如果你想重现这个问题:
运行
wget https://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip
在您的终端中解压文件...然后键入
make recover
进行编译(如果这不起作用,请使用
正常响)最后输入
./recover card.raw
到 运行 程序...它应该产生大约 50 个文件,但它又没有
即使没有合适的 header,您的最后一个 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
指向
到任意但可访问的内存,它可以偶然解释
这 undefined/uninitialised FILE
与标准相关
I/O;然后在标准 I/O 上发送任意字节可以冻结
终端...
但没有什么是不确定的...