简体   繁体   English

使用atoi函数从命令行输入

[英]Input from command line using atoi function

I have written a small program to check the page alignment. 我编写了一个小程序来检查页面对齐。 This program works fine when I hardcode the value of address variable in program itself, but when I try to take them from commandline using argc and argv values, the output goes haphazard, does the value of uint64_t cannot be recovered from commandline using atoi function..? 当我在程序本身中对address变量的值进行硬编码时,此程序可以正常工作,但是当我尝试使用argc和argv值从命令行中获取它们时,输出会变得很杂乱,确实无法使用atoi函数从命令行中恢复uint64_t的值。 。?

normal code, one can see the value of address being hardcoded into program itself. 普通代码,人们可以看到地址值被硬编码到程序本身中。

  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 }

output 产量

[souravhimanshu] ./aligned
Aligned to 0
Aligned to 0x80000000
Aligned to 0x40000000
Aligned to 0x20000000
Aligned to 0x10000000
Aligned to 0x8000000
Aligned to 0x4000000

code with command line input 带有命令行输入的代码

  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 }

output (incorrect) 输出(不正确)

    [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

as we can see the value of addr when printed after atoi function shows 0. 如我们所见,atoi函数显示0后打印时,addr的值。

kindly advise... 好心提醒...

数字0x924000000以十六进制表示,因此您应该使用strtol()并将其存储在long

addr=strtol(argv[1], NULL, 16);

You did not specify a platform, be aware that memory addresses are not necessarily the same size as int . 您没有指定平台,请注意,内存地址的大小不一定与int相同。 atoi returns an int , hence the problem. atoi返回一个int ,因此是问题所在。

Even long may not be large enough to hold a memory address (as in Windows IIRC). 即使long也可能不足以容纳内存地址(如Windows IIRC中一样)。 Therefore you should use strtoull returning an unsigned long long guaranteed to be at least 64 bits. 因此,您应该使用strtoull返回unsigned long long保证至少为64位。 Also use 0 as the base for conversion, allowing addresses to be entered as 0x80000000 on the command line. 还可以使用0作为转换的基础,从而允许在命令行上将地址输入为0x80000000 Also be more consistent and portable with your types: long is not necessarily 64 bits, so it should not be printed as "%lx" in printf . 还可以与您的类型更加一致和可移植: long不一定是64位,因此不应在printf中将其打印为"%lx"

Also work on your style. 也可以根据您的风格进行工作。 Consistency helps avoid bugs. 一致性有助于避免错误。

Here is a corrected version: 这是更正的版本:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM