简体   繁体   English

CS50-恢复-操纵Card.raw PSET3

[英]CS50 - Recovery - Manipulating Card.raw PSET3

So I'm a newbie struggling (drowning really) with C, trying to work my way through CS50. 因此,我是一名新手,正在C中苦苦挣扎(真的很困),试图通过CS50进行自己的尝试。 I'm working on the 'Recover' exercise, trying to recover jpegs from the card.raw file. 我正在进行“恢复”练习,试图从card.raw文件中恢复jpeg。 Through Googling, I have learnt that by typing xxd -l 2400 card.raw (char is 'L') in terminal, I can display bytes 0-2384 inclusive in terminal, which are in the following format: 通过Googling,我了解到,通过在终端中键入xxd -l 2400 card.raw(字符为“ L”),我可以在终端中显示0-2384字节(包括首尾),其格式如下:

0000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000000:0000 0000 0000 0000 0000 0000 0000 0000 ................

0000950: 0fe0 c11b e555 8f20 33cc fbfe 559e 8eee .....U. 0000950:0fe0 c11b e555 8f20 33cc fbfe 559e 8eee ..... U。 3...U... 3 ... U ...

Q1: I want to display the first 32 bytes (all 0's) using printf (so I can verify what is being read). Q1:我想使用printf显示前32个字节(全0)(以便我可以验证正在读取的内容)。 My program compiles, yet displays nothing. 我的程序可以编译,但是什么也不显示。 (Of course, once I have this working, I'll change it to display more bytes, as I know where the first jpeg starts from looking at the data in terminal). (当然,一旦完成此工作,我将其更改为显示更多字节,因为我知道第一个jpeg从查看终端中的数据开始的位置)。

Simple responses are appreciated (if I was more experienced, I wouldn't be posting such basic questions). 简单的回答是值得赞赏的(如果我更有经验,我不会发布这样的基本问题)。 Thanks, 谢谢,

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

int main()
{

    // hardcode opening of card.raw in read binary mode
    FILE *infile = fopen("card.raw", "rb");

    if (infile == NULL)
    {
        fprintf(stderr, "Could not open infile"); 
        return 2;
    } 

    // declare a variable to hold data to be read from infile file, note that a size for it must be specified
    char text[32];

    /* go to the beginning of the card.raw file to start reading */
    fseek(infile, 0, SEEK_SET);

    // text is the variable that will hold what is read, declared above
    // how many to read, how many to read at a time, where to read from
    fread(text, 32, 1, infile);
    printf("%s\n", text);
}

There are a couple of significant problems. 有几个重大问题。 First this declaration char text[32]; 首先,此声明为char text[32]; . Recall that char has a very specific meaning, it is evaluated as integers from 0 to 255; 回想一下char具有非常特殊的含义,它的取值范围是0到255之间的整数; it is "signed". 它是“签名”。 That is perfect for reading ascii text. 这是阅读ascii文本的完美选择。 Recall/review bmp.h from resize to see how data should be declared to read data that is not ascii text, like image data. resize调用/查看bmp.h,以查看应如何声明数据以读取 ascii文本的数据,例如图像数据。

-- edit -- Binary data needs to be an "unsigned" data type. -编辑-二进制数据必须是“无符号”数据类型。 In bmp.h, the author used uint8_t here typedef uint8_t BYTE; 在bmp.h中,作者在此处使用uint8_t typedef uint8_t BYTE; (which requires #include stdint.h> ). (这需要#include stdint.h> )。 You could use 你可以用
unsigned char text[32]

Secondly this printf("%s\\n", text); 其次,这个printf("%s\\n", text); . text is declared an array of chars. text被声明为字符数组。 But remember the thing that makes a string a string? 但是还记得使字符串变成字符串的事情吗? It is the terminating null byte, technically 0 . 它是终止的空字节,技术上为0 So when you ask printf to print text as a string it will print everything up to the first null byte ( 0 ). 因此,当您要求printf将text打印为字符串时,它将打印所有内容,直到第一个空字节( 0 )。 Which, as you can see from your hex dump, is the first byte in the file. 从十六进制转储中可以看到,它是文件中的第一个字节。

--edit-- Since you cannot use a string format in printf, you can print the ouptut one character at a time, much like mario or caesar. --edit--由于无法在printf中使用字符串格式,因此可以一次输出一个字符,就像mario或caesar一样。 However, since it is unsigned, the format string would be %u instead of %c . 但是,由于它是无符号的,所以格式字符串将是%u而不是%c You can see it in hex with the format string %04x ( x is the specifier for hex). 您可以使用格式为%04x十六进制格式查看它( x是十六进制的说明符)。

Thanks DinoCoderSAurus, with your (and some other help), I was able to figure out the following: 感谢DinoCoderSAurus,在您(和一些其他帮助)的帮助下,我能够找出以下几点:

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

int main()
{

    // hardcode opening of a file with fopen, in read binary mode
    FILE *infile = fopen("card.raw", "rb");
    // error check, did file open?
    if (infile == NULL)
    {
        fprintf(stderr, "Could not open infile"); 
        return 2;
    }

    // because card.raw contains binary/hex data, must use unsigned char to hold data, 32 bytes chosen at random
    unsigned char dataval[32];

    //    dataval is the variable that will hold what is read, declared above
    //          how many to read, how many to read at a time, where to read from
    fread(dataval, 1, 32, infile);

    //Print bytes (from dataval) one at a time
    for (int i = 0; i < 32; i++)
    {
        printf("%02X ", (int)dataval[i]);
    }
    printf("\n");

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM