【问题标题】:sprintf() usage, and gdb reporting program breaking out of loop early?sprintf() 的使用和 gdb 报告程序提前跳出循环?
【发布时间】:2015-09-01 16:53:31
【问题描述】:

我正在为一个类构建一个程序,该程序以 512 字节的块从原始文件中提取所有字节,在每个块的开始字节中搜索 JPG 签名,并在找到 JPG 签名后写出 JPG 图像。我已经成功地从原始文件中提取了一个 JPG,但是课程表明还有更多。在 GDB 中调试后,我注意到变量“jpgname”似乎从来没有值,而且,单步执行程序时,我经常跳到“fclose(inptr)”行,就好像它在 main while() 循环。我是否错误地使用了 GDB?我是否错误地使用了 sprintf()?我将不胜感激有关此问题的任何反馈。

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

typedef uint8_t  BYTE;


int main(void)
{
     BYTE jpg1[4] = {0xff, 0xd8, 0xff, 0xe0};
     BYTE jpg2[4] = {0xff, 0xd8, 0xff, 0xe1};
     int open = 0;
     FILE* outp;
     char* jpgname = malloc(sizeof(char) * 8);
     int counter;

     //TODO - MAKE sure this isn't a bunch of garbage data

    //open card file
    FILE* inptr = fopen("card.raw", "r");

    if (inptr == NULL)
    {
        printf("Could not open file\n");
        return 2;
    }

    BYTE buffer[512];
    fread(buffer, 512, 1, inptr);

    //repeat until end of card    
    while(fread(buffer, 512, 1, inptr) > 0)
    {                
            counter = 0;


            //start of new jpg?
            if((buffer[0] == jpg1[0] && buffer[1] == jpg1[1] && buffer[2] == jpg1[2] && buffer[3] == jpg1[3]) || (buffer[0] == jpg2[0] && buffer[1] == jpg2[1] && buffer[2] == jpg2[2] && buffer[3] == jpg2[3]))
            {

                sprintf(jpgname, "%d.jpg", counter); 
                if (open == 1)
                {
                    //close
                    fclose(outp);
                    //name new file
                    outp = fopen(jpgname, "w");
                    //write new
                    fwrite(buffer, sizeof(buffer), 1, outp);
                    counter++;
                }
                else if (open == 0)
                {
                    //write new file
                    outp = fopen(jpgname, "w");
                    fwrite(buffer, sizeof(buffer), 1, outp);
                    open = 1;
                    counter++;
                }
            }
            else
            {
                if(open == 1)
                {
                    fwrite(buffer, sizeof(buffer), 1, outp);
                }
            }
    } 

    fclose(outp);
    fclose(inptr);        
   //close any remaining files
}

【问题讨论】:

  • 表达式:sizeof(char) 被定义为 1,并且对发送到 malloc() 的值绝对没有影响。建议通过删除该表达式来整理代码。始终检查 (!=NULL) malloc() 的返回值以确保操作成功
  • 这一行:printf("Could not open file\n"); 不是处理从系统函数返回的错误的好方法。而是使用perror( "some text" );,因为 perror 将输出“一些文本”和系统错误消息,这些信息将由“errno”变量选择。
  • 调用fread() 紧跟while( fread() ) 意味着文件中的第一个JPG 将丢失
  • 在调用系统函数fopen()时,始终检查(!=NULL)返回值以确保操作成功
  • 是什么让您认为 jpg 文件将是 512 字节的精确倍数?建议遵循此页面中的详细信息:stackoverflow.com/questions/2517854/…>,因为它具有指向适当库的链接、jpeg 文件布局的讨论等。

标签: c file printf jpeg


【解决方案1】:
BYTE buffer[512];
fread(buffer, 512, 1, inptr);

//repeat until end of card    
while(fread(buffer, 512, 1, inptr) > 0)

你应该检查你为什么决定删除开始读入的 512 字节。

FILE* inptr = fopen("card.raw", "r");

您应该以 binary 模式打开输入文件和输出文件,例如:

FILE* inptr = fopen("card.raw", "rb");

outp = fopen(jpgname, "wb");

否则,读入或写出的数据可能会乱码。

【讨论】:

    【解决方案2】:

    虽然我感谢大家的意见,并因此使我的代码变得更好,但导致程序根本无法运行的错误是由于我的计数器在循环开始时被重置为 0。

    while(fread(buffer, 512, 1, inptr) > 0)
    {                
            counter = 0;
            ...
    }
    

    应该是

    counter = 0;
    while(fread(buffer, 512, 1, inptr) > 0)
    {
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 2023-03-17
      相关资源
      最近更新 更多