[英]CS50 Recover - How do I use sprintf? error: use of undeclared identifier 'filename'; did you mean 'rename'?
CS50 是我的第一次编码体验,我无法通过 Recover。 我正在参加在线免费课程,并且我正在自己工作,这些问题集对我来说非常困难。 如果我的代码和问题看起来很新手,我提前道歉。
一些问题:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
// check usage
if (argc != 2)
{
printf("Please enter only 1 argument\n");
return 1;
}
// open file
FILE *file = fopen(argv[1],"r");
if (file == NULL)
{
printf("Usage: ./recover usage\n");
return 1;
}
int count = 0;
// Read first 4 bytes
unsigned char buffer[4];
while(fread(buffer, 512, 1, file) == 512);
// check first 4 bytes
if (buffer[0] == 0xff &&
buffer[1] == 0xd8 &&
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
// count this 512B block
{
if (count == 0) // if first jpeg
{
sprintf(filename, "%03i.jpg", count); // last number is ith filename
FILE *img = fopen(filename, "w"); // writing to filename
fwrite(buffer, 512, 1, filename); // write to buffer 512 bytes at a time to filename
}
else
{
fclose(filename);
count++; // add to existing count
sprintf(filename, "%03i.jpg", count); // last number is ith filename
FILE *img = fopen(filename, "w"); // writing to filename
fwrite(buffer, 512, 1, filename); // write to buffer 512 bytes at a time to filename
}
}
else
{
if (count > 1)
{
sprintf(filename, "%03i.jpg", count); // last number is ith filename
FILE *img = fopen(filename, "a"); // writing to filename
fwrite(buffer, 512, 1, filename); // write to buffer 512 bytes at a time to filename
}
}
fclose(argv[1]);
}
这是我的错误代码: ~/pset4/recover/ $ make recover clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow recover.c -lcrypt -lcs50 -lm -o recover recover.c:33:25:错误:使用未声明的标识符“文件名”; 您指的是 'rename' 吗? sprintf(文件名,“%03i.jpg”,计数); // 最后一个数字是第 i 个文件名 ^~~~~~~~ 重命名
recover.c:57:12:错误:不兼容的指针类型将 'char *' 传递给 'FILE *' 类型的参数(又名 'struct _IO_FILE *')[-Werror,-Wincompatible-pointer-types] fclose(argv[1 ]); ^~~~~~~ /usr/include/stdio.h:199:26: 注意:在此处将参数传递给参数'__stream' extern int fclose (FILE *__stream); ^ 产生 11 个错误。 : 目标“恢复”的配方失败 make: *** [recover] 错误 1
您的代码中存在许多问题。 有些有“简单”的修复,有些我只能做出“智能猜测”。
首先,您正在使用filename
变量来写入 output 文件的名称,但永远不要声明; 这是一个简单的修复:声明一个char filename[512];
变量(或任何大小,代替 512,你觉得是必要的)。
其次, fclose
function 将先前打开的FILE*
'handle' 作为其参数; 在您的代码中,这将是file
变量(用于输入文件)或img
变量(用于输出)。
第三,您的代码对img
变量使用了非常“本地”的定义,这些定义不会在不同的if... else
块之间共享; 要解决此问题,请在更“外部”的 scope 中声明变量,然后在其他各个地方使用它(无需重新声明)。
其他问题是你的while (fread(buffer, 512, 1, file) == 512);
语句正在读取很多次(可能),但以下代码仅在读取操作失败后执行,这几乎肯定不是您需要的; 因此,您应该有一个{... }
块将(大部分)以下代码包含在该while
循环中。
还有几个地方我认为你应该关闭 output 文件:一旦进入循环,你“重新打开”一个新的 output,然后在整个大循环完成后关闭“悬空”打开文件处理。
我在下面的代码中添加了带有三斜杠 ( ///
) 的注释,以解决这些问题。 请随时要求任何进一步的澄清和/或解释。
int main(int argc, char* argv[])
{
// check usage
if (argc != 2) {
printf("Please enter only 1 argument\n");
return 1;
}
// open file
FILE* file = fopen(argv[1], "r");
if (file == NULL) {
printf("Usage: ./recover usage\n");
return 1;
}
int count = 0;
/// TEST first 4 bytes
unsigned char buffer[512]; /// This needs to be 512 bytes - not just the first 4 that you test!!
char filename[512]; /// Buffer in which to write filename string
FILE* img = NULL; /// This variable MUST be in the more outer scope!
while (fread(buffer, 1, 512, file) == 512) { /// count and size were round the wrong way!
// check first 4 bytes
if (buffer[0] == 0xff &&
buffer[1] == 0xd8 &&
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
// count this 512B block
{
if (count == 0) { // if first jpeg
sprintf(filename, "%03i.jpg", count); // last number is ith filename
img = fopen(filename, "w"); /// Don't (re)declare a local "img"
fwrite(buffer, 1, 512, img); /// Use FILE* handle, not name!
}
else {
fclose(img); /// Use FILE* handle, not name!
count++; // add to existing count
sprintf(filename, "%03i.jpg", count); // last number is ith filename
img = fopen(filename, "w"); /// Don't (re)declare a local "img"
fwrite(buffer, 1, 512, img); /// Use FILE* handle, not name!
}
}
else {
if (count > 1) {
fclose(img); /// I THINK you need to close the old file first!
sprintf(filename, "%03i.jpg", count); // last number is ith filename
img = fopen(filename, "a"); // writing to filename
fwrite(buffer, 1, 512, img); // write to buffer 512 bytes at a time to filename
}
}
}
fclose(img); /// At SOME point (probably here) you should close the remaining opened output file!
fclose(file); /// Use FILE* handle, not name!
return 0;
}
此外,为了彻底,您确实应该检查img - fopen(...)
调用的每个结果,如果曾经是NULL
,则添加某种错误处理(正如您在打开输入文件时所做的那样)。
感谢 Adrian Mole 的指点,我完成了如下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
// check usage
if (argc != 2)
{
printf("Please enter only 1 argument\n");
return 1;
}
// open file
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
printf("Usage: ./recover usage\n");
return 1;
}
int count = 0; // create count integer
unsigned char buffer[512]; /// This needs to be 512 bytes - not just the first 4 that you test!!
char filename[512]; // Buffer in which to write filename string
FILE *img = NULL; // This variable MUST be in the more outer scope!
while (fread(buffer, 1, 512, file) == 512) // count and size were round the wrong way!
{
// check first 4 bytes
if (buffer[0] == 0xff &&
buffer[1] == 0xd8 &&
buffer[2] == 0xff &&
(buffer[3] & 0xf0) == 0xe0)
// count this 512B block
{
if (count == 0) // if first jpeg
{
count++;
sprintf(filename, "%03i.jpg", count - 1); // last number is ith filename
img = fopen(filename, "w"); // Don't (re)declare a local "img"
fwrite(buffer, 1, 512, img); // using img handle
}
else
{
fclose(img); /// Use FILE* handle, not name!
count++; // add to existing count
sprintf(filename, "%03i.jpg", count - 1); // last number is ith filename
img = fopen(filename, "w"); // Don't (re)declare a local "img"
fwrite(buffer, 1, 512, img); // Using img handle
}
}
else
{
if (count > 0)
{
fwrite(buffer, 1, 512, img); // write to buffer 512 bytes at a time to filename
}
else
{
continue;
}
}
}
fclose(img); // At SOME point (probably here) you should close the remaining opened output file!
fclose(file); // Use FILE* handle, not name!
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.