简体   繁体   中英

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..?

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.

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 . atoi returns an int , hence the problem.

Even long may not be large enough to hold a memory address (as in Windows IIRC). Therefore you should use strtoull returning an unsigned long long guaranteed to be at least 64 bits. Also use 0 as the base for conversion, allowing addresses to be entered as 0x80000000 on the command line. 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 .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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