C 使用atoi函数从命令行输入
我已经写了一个小程序来检查页面对齐。 当我在程序本身中硬编码address变量的值时,该程序运行良好,但当我尝试使用argc和argv值从命令行获取它们时,输出变得随意,uint64_t的值是否无法使用atoi函数从命令行恢复 在普通代码中,可以看到地址的值被硬编码到程序本身中C 使用atoi函数从命令行输入,c,memory-alignment,atoi,C,Memory Alignment,Atoi,我已经写了一个小程序来检查页面对齐。 当我在程序本身中硬编码address变量的值时,该程序运行良好,但当我尝试使用argc和argv值从命令行获取它们时,输出变得随意,uint64_t的值是否无法使用atoi函数从命令行恢复 在普通代码中,可以看到地址的值被硬编码到程序本身中 1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int aligned(uint64_t addr, uint64_t pgsize){
1 #include<stdio.h>
2 #include<stdlib.h>
3
4 int aligned(uint64_t addr, uint64_t pgsize){
5 return ((uint64_t)addr % pgsize == 0);
6 }
7
8 int main(int argc, char*argv[]){
9 uint32_t i;
10 uint64_t addr, size;
11 addr=0x1900000000;
12 size=0x100000000 ;
13
14 for(i=0;i<7;i++)
15 if(aligned(addr,size>>i)){
16 printf("Aligned to %#lx\n",size>>i);
17 }
18 else
19 printf("Not Aligned to %#lx\n",size>>i);
20 return 0;
21 }
使用命令行输入的代码
1 #include<stdio.h>
2 #include<stdlib.h>
3
4 int aligned(uint64_t addr, uint64_t pgsize){
5 return ((uint64_t)addr % pgsize == 0);
6 }
7
8 int main(int argc, char*argv[]){
9 uint32_t i;
10 uint64_t addr, size;
11 if(argc<2){
12 printf("usage ./chkalign <address>\n");
13 exit(-1);
14 }
15 addr=atoi(argv[1]);
16 printf("%#lx",addr);
17 //addr=0x1900000000;
18 size=0x100000000 ;
19
20 for(i=0;i<7;i++)
21 if(aligned(addr,size>>i)){
22 printf("Aligned to %#lx\n",size>>i);
23 }
24 else
25 printf("Not Aligned to %#lx\n",size>>i);
26 return 0;
27 }
正如我们可以看到的那样,在atoi函数显示0后打印addr的值
请告知……数字
0x924000000
为十六进制,因此您应使用strtol()
并将其存储在long
addr=strtol(argv[1], NULL, 16);
您没有指定平台,请注意内存地址的大小不一定与
int
相同atoi
返回一个int
,因此出现问题
即使long
也可能不够大,无法容纳内存地址(如在Windows IIRC中)。因此,您应该使用strtoull
返回保证至少为64位的无符号long-long
。还可以使用0
作为转换的基础,允许在命令行上以0x8000000
的形式输入地址。也要与您的类型更加一致和可移植:long
不一定是64位的,因此它不应该在printf
中打印为%lx“
也要培养你的风格。一致性有助于避免错误
以下是更正的版本:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int aligned(uint64_t addr, uint64_t pgsize) {
return (addr % pgsize) == 0;
}
int main(int argc, char *argv[]) {
int i;
uint64_t addr, size;
if (argc < 2) {
printf("usage: ./chkalign <address>\n");
exit(-1);
}
addr = strtoull(argv[1], NULL, 0);
printf("Address %#llx:\n", (unsigned long long)addr);
//addr = 0x1900000000;
size = 0x100000000;
for (i = 0; i < 7; i++) {
if (aligned(addr, size >> i)) {
printf("Aligned to %#llx\n", (unsigned long long)size >> i);
} else {
printf("Not Aligned to %#llx\n", (unsigned long long)size >> i);
break;
}
}
return 0;
}
#包括
#包括
#包括
整数对齐(uint64地址,uint64地址大小){
返回(地址%pgsize)==0;
}
int main(int argc,char*argv[]){
int i;
uint64地址、尺寸;
如果(argc<2){
printf(“用法:./chkalign\n”);
出口(-1);
}
addr=strtoull(argv[1],NULL,0);
printf(“地址%#llx:\n”,(无符号长-长)地址);
//地址=0x1900000000;
大小=0x100000000;
对于(i=0;i<7;i++){
如果(对齐(地址、大小>>i)){
printf(“对齐到%#llx\n”,(无符号长)大小>>i);
}否则{
printf(“未对齐到%#llx\n”,(无符号长)大小>>i);
打破
}
}
返回0;
}
您是否尝试了strtol()
?不要包含行号,否则我们无法将您的代码复制/粘贴到文本编辑器中并编译。在这里询问时,请将您的代码简化为最少的示例。你的问题与翻译地址无关。正如您在标题中正确指出的那样,您在atoi
方面存在问题,因此请解决该问题,并省略所有不感兴趣的内容。请不要在代码示例中使用行号,这会使CPR(剪切粘贴并运行)和PCV(发布更正版本)复杂化.strtoul
在这种情况下更有意义。使用0
而不是16
将允许以更通用的格式读取数字,十进制、八进制或十六进制。使用strtoull addr=strtoull(argv[1],NULL,0);打印不正确的地址时。/chkalign 0x924000000 addr:0x24000000而不是0x924000000它取决于平台上long
的大小。在Windows中只有32位。检查我的答案。
addr=strtol(argv[1], NULL, 16);
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int aligned(uint64_t addr, uint64_t pgsize) {
return (addr % pgsize) == 0;
}
int main(int argc, char *argv[]) {
int i;
uint64_t addr, size;
if (argc < 2) {
printf("usage: ./chkalign <address>\n");
exit(-1);
}
addr = strtoull(argv[1], NULL, 0);
printf("Address %#llx:\n", (unsigned long long)addr);
//addr = 0x1900000000;
size = 0x100000000;
for (i = 0; i < 7; i++) {
if (aligned(addr, size >> i)) {
printf("Aligned to %#llx\n", (unsigned long long)size >> i);
} else {
printf("Not Aligned to %#llx\n", (unsigned long long)size >> i);
break;
}
}
return 0;
}