我正在用C语言编写一个缓存模拟器,并且几乎完成了所有工作……除非我尝试扫描地址fscanf跳过了十六进制数字中的一些数字:它只会得到4个字节!如果我找不到正确的地址,则标记位不正确,并且模拟将始终无法进行。任务似乎很简单,但是我一定错过了一些东西。也许与fscanf格式的字符串特质有关?

源文件如下所示:

 S 00600aa0,1
I  004005b6,5
 S 7ff000398,8
 M 7ff000390,8
// and so on ...


我尝试使用fgets和sscanf代替,但是得到的结果相同。

char buffer[200];
char *pattern = " %c %x,%s\n";
int status; long address; char op;
while ((status = fscanf(source, pattern, &op, &address, buffer)) != EOF) {
    if (op != 'I')  {
        fprintf(stderr,"address: %x\n",address); // DEBUG stmnt
        simulate the cache..........................


debug语句为第3行打印出错误的地址,而不是“ address:7ff000398”,而是写入“ address:ff000398”。它正确地适合第1行。为什么只读取前4个字节? “地址”已经很长了,我找不到关于%x的任何文档,就像这样。

最佳答案

您将需要一个64位整数来存储结果。

32位系统

在32位系统上,long类型可能只有32位长。

可以肯定的是,您可以对long long使用address类型。

更好的是使用uint64_t类型(在c99的stdint.h中定义)

变化


address类型更改为long long(如果需要)
%x更改为%lx(对于long)或%llx(对于long long)(两个地方)
在打开警告的情况下进行编译。


警告事项

启用警告后,您将收到以下消息:

warning: format ‘%x’ expects argument of type ‘unsigned int’,
but argument 3 has type ‘long int’ [-Wformat=]
fprintf(stderr,"address: %x\n",address); // DEBUG stmnt
                         ~^    ~~~~~~~
                         %lx


这为您解决问题提供了一个很好的线索。

因此,您的代码应如下所示:

#include <stdio.h>
int main(void)
{
    char buffer[10];
    char *pattern = " %c %lx,%s\n";
    int status;
    unsigned long address; char op;
    while ((status = scanf(pattern, &op, &address, buffer)) != EOF) {
        fprintf(stderr,"address: %lx\n",address);
    }
    return 0;
}


通过您的输入,我得到的结果是:

address: 600aa0
address: 4005b6
address: 7ff000398
address: 7ff000390

关于c - fscanf仅获取十六进制数字的前4个字节,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56164194/

10-12 01:28
查看更多