我正在用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/