3

我有一个小挑战(可以在页面底部找到,标题是 CSI。https ://x.cs50.net/2012/psets/4/pset4.html,太长了,我无法粘贴。) (不,我不是想作弊,我已经找到了完整的代码解决方案,但我希望我的工作..

工作是在 .raw 文件中嗅出 JPG 文件(文件已上传)

我正在使用下面显示的代码:

 #include <stdio.h>

 int main(void){
    FILE* fp = fopen("card.raw", "r");
    if (fp == NULL){
        printf("error!");
    }
    char foo[512];
    fread(foo,sizeof(foo),sizeof(foo[0]), fp);
    for(int j = 0; j < 20000; j++) {
        if (foo[0] == 0xff){
            printf("jackpot");
            return 0;
        }
        else {
            printf(" %d ", foo[0]);
            fread(foo,sizeof(foo),sizeof(foo[0]), fp);
        }
    }
}

问题是,我不知道我做错了什么。它应该在达到 0xff 时立即尖叫并退出,但它会继续前进。 如果需要,可以在https://mega.co.nz/#!tZcFWYIS!DmPAGT7FHLFgtW0SorWU-SE-gfJfR7MlbxdNucN1Biw找到文件是。

更新:感谢大家的帮助,我终于中奖了。这是我最终得到的结束代码。

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

typedef uint8_t BYTE;
int main(void){
    FILE* fp = fopen("card.raw", "rb");
    if (fp == NULL){
        printf("error!");
    }
    BYTE foo[512];    
    for (int j = 0;fread(foo,sizeof(foo),sizeof(foo[0]), fp) > 0; j++){
        if (foo[0] == 0xff){
            printf("jackpot, %d", j);
            return 0;
        }
    }
}
4

2 回答 2

3

我的猜测是您正在以"r"模式读取文件,这可能会转换换行符并弄乱块同步。

"rb"尝试以模式(二进制模式)读取文件。

于 2013-04-09T08:55:53.327 回答
2

我看到你有两个问题。

一个是除了你读取的块的第一个字节之外,你并没有真正检查任何东西。第二个是您继续阅读而不考虑文件结尾或错误。

您应该重新设计以循环读取(同时检查错误和文件结尾),并在该循环中使用另一个循环来查找您正在寻找的字节序列。


像这样的东西:

for (;;)
{
    size_t nread = fread(...);
    if (nread == 0)
    {
        /* Error or end-of-file */
        break;
    }

    for (int i = 0; i < nread; i++)
    {
        /* Check for signature in `foo[i]` */
    }
}

如果仅在每个 512 字节块的开头找到签名,则不需要第二个内部循环,并且可以大大简化它:

while (fread(...) > 0)
{
    /* Check for signature in `foo[0]` */
}
于 2013-04-09T08:53:34.567 回答