这是我为检查输入是否为正整数而写的
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int isInt(char num[3]) {
int l = strlen(num);
int x;
for ( x = 0; x < l; x++) {
if ( ! isdigit(num[x]) )
return 0;
}
return 1;
}
int main(void) {
int i;
char str[3];
printf("Enter a positive integer: ");
scanf("%s", str);
if ( isInt(str) == 1 ) {
i = atoi(str);
printf("%d n", i);
} else {
printf("This is not a positive integer! n");
}
return 0;
}
我发现了一些意想不到的行为,尽管程序似乎可以工作:
无论我是否
#include <ctype.h>
,都没有区别。isdigit()
函数在没有库的情况下如何工作?(我在ubuntu 14.04上使用gcc 4.9.3)如果我强制
str
是一个长度为3的字符串,那么当我运行./a.out
时,它怎么可能正确检查并打印大于999的数字?如果我输入5678,str
不应该只保存567吗?或者它可以保存前2^3个数字?我很困惑如果我想检查一个字符串是否是正整数,但数字可能很大,那么
str
应该有多大?难道没有办法把它做成需要的那么大吗?
-
头文件不是库;它只说明如何使用图书馆。如果省略了头文件,那么编译器将不得不猜测函数的参数,但如果猜测正确(或足够接近),那么所有函数都可能正常工作。(事实上,这并不是"猜测";当然,这是有规则的。)
-
您没有"强加"
str
的长度限制,而是保留了3个字节的空间。如果您超出了该保留,那么程序可能会(也可能不会)继续正常工作,但您可能会发现其他数据意外损坏。没有可靠的方法来预测哪些数据会被覆盖;它是未定义的。 -
不,在用户输入数字之前,无法知道数字有多大,但例如,您可以使用
%3s
设置将读取的最大字符数。但是,您需要确保为字符串末尾的' '
nul字符终止符保留足够的空间。您也可以使用scanf
的替代方案来读取块中的数据,但最安全的方法可能是使用"大"缓冲区和最大字段宽度。请注意,scanf可以直接读取数字,而无需将其作为字符串读取,然后自己进行转换。
关于第3点:
不,没有办法提前知道。
然而,很容易创建一个函数,以较小的部分读取输入,并将它们连接到一个大缓冲区中。大缓冲区将动态分配,以便在需要时增长。用户必须免费呼叫。
这里有一个实现:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define INCREMENT_SIZE 20
#define SMALL_SIZE 10
char* read_long_string(void)
{
char* all;
char* tmp;
int all_size;
char some[SMALL_SIZE];
all_size = INCREMENT_SIZE;
all = malloc(all_size);
if (!all)
{
// Out of mem
return NULL;
}
all[0] = ' ';
while(1)
{
// Make sure "all" has room for all bytes in "some"
while(all_size - strlen(all) < sizeof(some))
{
all_size += INCREMENT_SIZE;
tmp = realloc(all, all_size); // Allocate more memory
if (!tmp)
{
// Out of mem
free(all);
return NULL;
}
all = tmp;
}
// Read bytes into "some"
if (!fgets(some, sizeof(some), stdin))
{
// Error
free(all);
return NULL;
}
if (strlen(some) > 0)
{
// Add the bytes to "all"
strcat(all, some);
// Check if newline has been pressed
if (some[strlen(some)-1] == 'n')
{
// done
return all;
}
}
}
}
int main(int argc, char const *argv[])
{
char* s;
printf("Enter a positive integer:n");
s = read_long_string();
if (s) printf("%s", s);
free(s);
return 0;
}