使用 atoi 函数从命令行输入
Input from command line using atoi function
我写了一个小程序来检查页面对齐。
当我在程序本身中硬编码地址变量的值时,该程序工作正常,但是当我尝试使用 argc 和 argv 值从命令行获取它们时,输出变得随意,uint64_t 的值是否无法从命令行恢复使用 atoi 函数..?
正常代码,可以看到地址的值被硬编码到程序本身。
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 }
输出
[souravhimanshu] ./aligned
Aligned to 0
Aligned to 0x80000000
Aligned to 0x40000000
Aligned to 0x20000000
Aligned to 0x10000000
Aligned to 0x8000000
Aligned to 0x4000000
带命令行输入的代码
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 }
输出(不正确)
[sourav@himanshu] ./chkalign 0x924000000
0Aligned to 0
Aligned to 0x80000000
Aligned to 0x40000000
Aligned to 0x20000000
Aligned to 0x10000000
Aligned to 0x8000000
Aligned to 0x4000000
我们可以看到在atoi函数显示0后打印的addr的值。
请指教...
数字 0x924000000
是十六进制的,所以你应该使用 strtol()
并将其存储在 long
addr=strtol(argv[1], NULL, 16);
您没有指定平台,请注意内存地址的大小不一定与 int
相同。 atoi
returns 一个 int
,因此是问题。
甚至 long
也可能不够大以容纳内存地址(如 Windows IIRC)。因此,您应该使用 strtoull
返回保证至少为 64 位的 unsigned long long
。还使用 0
作为转换的基础,允许在命令行上将地址输入为 0x80000000
。还与您的类型更加一致和可移植: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;
}
我写了一个小程序来检查页面对齐。 当我在程序本身中硬编码地址变量的值时,该程序工作正常,但是当我尝试使用 argc 和 argv 值从命令行获取它们时,输出变得随意,uint64_t 的值是否无法从命令行恢复使用 atoi 函数..?
正常代码,可以看到地址的值被硬编码到程序本身。
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 }
输出
[souravhimanshu] ./aligned
Aligned to 0
Aligned to 0x80000000
Aligned to 0x40000000
Aligned to 0x20000000
Aligned to 0x10000000
Aligned to 0x8000000
Aligned to 0x4000000
带命令行输入的代码
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 }
输出(不正确)
[sourav@himanshu] ./chkalign 0x924000000
0Aligned to 0
Aligned to 0x80000000
Aligned to 0x40000000
Aligned to 0x20000000
Aligned to 0x10000000
Aligned to 0x8000000
Aligned to 0x4000000
我们可以看到在atoi函数显示0后打印的addr的值。
请指教...
数字 0x924000000
是十六进制的,所以你应该使用 strtol()
并将其存储在 long
addr=strtol(argv[1], NULL, 16);
您没有指定平台,请注意内存地址的大小不一定与 int
相同。 atoi
returns 一个 int
,因此是问题。
甚至 long
也可能不够大以容纳内存地址(如 Windows IIRC)。因此,您应该使用 strtoull
返回保证至少为 64 位的 unsigned long long
。还使用 0
作为转换的基础,允许在命令行上将地址输入为 0x80000000
。还与您的类型更加一致和可移植: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;
}