c';她正在改变我的计数器

c';她正在改变我的计数器,c,cs50,C,Cs50,我正在处理CS50的一个赋值,但在运行sprintf函数后,我发现计数器变量有一个奇怪的行为: //recover jpg files from memory #include <stdio.h> #include <stdint.h> typedef uint8_t BYTE; int main(int argc, char *argv[]) { // ensure proper usage if (argc != 2) {

我正在处理CS50的一个赋值,但在运行sprintf函数后,我发现计数器变量有一个奇怪的行为:

//recover jpg files from memory

#include <stdio.h>
#include <stdint.h>

typedef uint8_t  BYTE;

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        fprintf(stderr, "Please submit an input file\n");
        return 1;
    }

    // remember filename
    char *infile = argv[1];

    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    // define the buffer as array of BYTEs
    BYTE buffer[512];

    // define the counter of images found
    int counter = 0;

    // declare the array for the filename
    char filename[3];

    while (fread(buffer, 512, 1, inptr)>0)
        {

        if (buffer[0] == 0xff &&
            buffer[1] == 0xd8 &&
            buffer[2] == 0xff &&
            (buffer[3] & 0xf0) == 0xe0)
        {
            sprintf(filename, "%03i.jpg", counter);
            printf("%c%c%c\n", filename[0],filename[1],filename[2]);
            counter++;
        }
    }
}
//从内存中恢复jpg文件
#包括
#包括
typedef uint8_t字节;
int main(int argc,char*argv[])
{
//确保正确使用
如果(argc!=2)
{
fprintf(stderr,“请提交输入文件”\n);
返回1;
}
//记住文件名
char*infle=argv[1];
//打开输入文件
文件*inptr=fopen(填入“r”);
如果(inptr==NULL)
{
fprintf(stderr,“无法打开%s。\n”,填充);
返回2;
}
//将缓冲区定义为字节数组
字节缓冲区[512];
//定义找到的图像的计数器
int计数器=0;
//声明文件名的数组
字符文件名[3];
而(fread(缓冲区,512,1,inptr)>0)
{
如果(缓冲区[0]==0xff&&
缓冲区[1]==0xd8&&
缓冲区[2]==0xff&&
(缓冲区[3]&0xf0)==0xe0)
{
sprintf(文件名为“%03i.jpg”,计数器);
printf(“%c%c%c\n”,文件名[0],文件名[1],文件名[2]);
计数器++;
}
}
}
我尝试了debug50工具,发现在运行fprintf之后,变量计数器从0传递到一个很大的奇怪数字


关于问题在哪里以及如何解决问题,有什么建议吗?

多亏了我收到的错误评论:


<>我忘记考虑“文件名”变量的正确长度,当运行SaveTFF时,我超过了它允许的内存

<代码>文件名不够大,不能容纳<代码> %03i。JPG < /代码> -它的大小为3,需要大小8。因此,您的
sprintf
调用调用了未定义的行为为什么大小为9?不是3个字符?变量按*inptr、buffer、counter、filename的顺序存储在内存中。所以,如果计数器被损坏,缓冲区可能会超过512大小。“001.jpg”比3个字符多得多(不包括bean计数:),除非在RAM受限的嵌入式环境中,对于本地字符数组,只需使用[128]作为最小值,即使这样,也要使用不能写越界的代码。这是一个容易犯的错误。一个好习惯是总是调用
snprintf(filename,sizeof(filename),“%03i.jpg”,counter)
snprintf
sprintf
的一个版本,它允许您传入数组的大小,这样
snprintf
就可以保证不会溢出数组。(不过,请注意,如果
filename
不是数组,而是指向其他字符缓冲区的指针,
sizeof
不会执行您想要的操作,您必须传递其他内容才能为
snprintf
提供正确的大小。)