2015-02-12 153 views
1

我試圖驗證我的程序的用戶在命令行中輸入了一個有效的整數。我遇到了一個問題:它拒絕所有輸入。檢查命令行輸入是否爲有效整數(C)

這裏就是我有

// Make sure input is a valid int 
char *ptr = NULL; 
long int input = strtol(argv[i+1], &ptr, 10); 
if(ptr == NULL){ 
    userMinInt = input; 
    minIntSet = true;  
} 
else 
    fprintf(stderr, "You must enter a valid integer for <min-int>. Using default value of %ld\n", minInt); 
+0

我覺得http://stackoverflow.com/questions/19206660/how-to-write-own-isnumber-function回答了這個。 – peter 2015-02-12 03:15:13

+0

@peter啊,我明白了。所以你不檢查你檢查的空(char)0; – JayB 2015-02-12 03:18:47

+0

'我'是什麼?確保你在做這個之前檢查'i + 1 2015-02-12 03:23:53

回答

0

感謝Peter,我已經解決了這個問題。這裏是新的工作代碼:

// Make sure input is a valid int 
char *ptr = NULL; 
long int input = strtol(argv[i+1], &ptr, 10); 
if(ptr != NULL && *ptr == (char)0){ 
    userMinInt = input; 
    minIntSet = true; 
} 
else 
    fprintf(stderr, "You must enter a valid integer for <min-int>. Using default value of %ld\n", minInt); 
+0

轉換是不必要的,你可以在不改變程序行爲的情況下將其刪除。 – 2015-02-12 03:24:38

+0

@MattMcNabb Isnt(int)0在C中等於NULL嗎? – JayB 2015-02-12 03:45:11

+1

不完全。 'NULL'是一個可擴展爲'0'或'(void *)0'的宏,它應該用在需要指針的地方。這與'* ptr == 0'無關。 – 2015-02-12 04:28:18

1

代碼正在檢查結束指針是否爲NULL。相反,代碼應檢查:

1)結束指針是否指向空字符'\0'
2)結束指針是否與開始不同?

低於其他檢查:

char *start = argv[i+1]; // maybe should be argv[i] 
char *ptr; 
// set errno to 0 for subsequent check 
errno = 0; 
long int input = strtol(start, &ptr, 10); 
if (ptr == start) { 
    fprintf(stderr, "No conversion done.\n"); 
} 
else if (*ptr != 0) { 
    fprintf(stderr, "Extra data after the number.\n"); 
} 
else if (errno) { 
    fprintf(stderr, "Number outside long range.\n"); 
} 
else if (input < INT_MIN || input > INT_MAX) { 
    fprintf(stderr, "Number %ld outside int range.\n", input); 
} 
else { 
    printf("Number is %d.\n", (int) input); 
} 
+0

我認爲'if(errno)'應該是'if((input == LONG_MIN || input == LONG_MAX)&& errno == ERANGE)' - 'errno'可以在成功時更改。 – mafso 2015-02-12 12:07:51

+0

@mafso同意提出的'if()'可以工作,但對它的需要不同意。調用strtol()會在範圍錯誤上設置errno,否則它不會被改變:「如果函數調用了庫函數調用,errno的值可以設置爲非零在本國際標準的功能描述中沒有記錄使用'errno'。「 C11§7.53和'strtol()'spec包含:「...如果正確的值超出了可表示值的範圍,...宏ERANGE的值存儲在'errno'中。」 §7.22.1.4 – chux 2015-02-12 15:49:46

+0

有趣。 Linux的手冊頁似乎與此矛盾(特別是代碼示例)。標準C函數和POSIX或GNU函數可能有所不同嗎?無論如何,我在這裏確信這個案子。謝謝! – mafso 2015-02-12 16:13:07