提问人:Astinog 提问时间:5/20/2013 更新时间:10/9/2023 访问量:203750
如何检查字符串是否为数字?
How to check if a string is a number?
问:
我想检查字符串是否是带有此代码的数字。我必须检查字符串中的所有字符是否都是整数,但 while 返回始终是 isDigit = 1。我不知道为什么如果不起作用。
char tmp[16];
scanf("%s", tmp);
int isDigit = 0;
int j=0;
while(j<strlen(tmp) && isDigit == 0){
if(tmp[j] > 57 && tmp[j] < 48)
isDigit = 0;
else
isDigit = 1;
j++;
}
答:
if(tmp[j] >= '0' && tmp[j] <= '9') // should do the trick
忘记 ASCII 代码检查,使用 或(参见 man isnumber
)。第一个函数检查字符是否为 0–9,第二个函数还接受各种其他数字字符,具体取决于当前区域设置。isdigit
isnumber
甚至可能有更好的函数来执行检查——重要的教训是,这比看起来要复杂一些,因为“数字字符串”的精确定义取决于特定的语言环境和字符串编码。
评论
-
.
isdigit
并且是非常好的功能。但是,如果您想确切地学习如何将数字与其他字符区分开来,它们真的很糟糕。学习函数的基础知识,或者更准确地说,函数的工作原理,比学习如何使用函数更重要。对我来说,这个答案是正确的,但从长远来看对 OP 没有任何帮助。他仍然不知道如何区分其他语言中缺少 和 的数字。只有我的 2 美分。isnumber
isdigit
isnumber
在代码的这一部分中:
if(tmp[j] > 57 && tmp[j] < 48)
isDigit = 0;
else
isDigit = 1;
您的条件将始终为 false,导致始终设置为 。您可能想要:if
isDigit
1
if(tmp[j] > '9' || tmp[j] < '0')
isDigit = 0;
else
isDigit = 1;
但是,这可以简化为:
isDigit = isdigit(tmp[j]);
但是,循环的逻辑似乎有点误导:
int isDigit = 0;
int j=0;
while(j<strlen(tmp) && isDigit == 0){
isDigit = isdigit(tmp[j]);
j++;
}
由于不是一个常量,因此不确定编译器是否会优化每次迭代的长度计算。tmp
正如@andlrc在评论中建议的那样,您可以只检查数字,因为终止的 NUL 无论如何都会无法通过检查。
while (isdigit(tmp[j])) ++j;
评论
for (char *ptmp = tmp; isdigit(*ptmp); ptmp++);
可能会更好。
isdigit()
'\0'
您的病情表明。 不能同时大于 57 和小于 48。if X is greater than 57 AND smaller than 48
X
if(tmp[j] > 57 && tmp[j] < 48)
它应该是:if X is greater than 57 OR smaller than 48
if(tmp[j] > 57 || tmp[j] < 48)
我需要为我目前正在从事的项目做同样的事情。以下是我解决问题的方法:
/* Prompt user for input */
printf("Enter a number: ");
/* Read user input */
char input[255]; //Of course, you can choose a different input size
fgets(input, sizeof(input), stdin);
/* Strip trailing newline */
size_t ln = strlen(input) - 1;
if( input[ln] == '\n' ) input[ln] = '\0';
/* Ensure that input is a number */
for( size_t i = 0; i < ln; i++){
if( !isdigit(input[i]) ){
fprintf(stderr, "%c is not a number. Try again.\n", input[i]);
getInput(); //Assuming this is the name of the function you are using
return;
}
}
评论
更明显和简单的线程安全示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
if (argc < 2){
printf ("Dont' forget to pass arguments!\n");
return(-1);
}
printf ("You have executed the program : %s\n", argv[0]);
for(int i = 1; i < argc; i++){
if(strcmp(argv[i],"--some_definite_parameter") == 0){
printf("You have passed some definite parameter as an argument. And it is \"%s\".\n",argv[i]);
}
else if(strspn(argv[i], "0123456789") == strlen(argv[i])) {
size_t big_digit = 0;
sscanf(argv[i], "%zu%*c",&big_digit);
printf("Your %d'nd argument contains only digits, and it is a number \"%zu\".\n",i,big_digit);
}
else if(strspn(argv[i], "0123456789abcdefghijklmnopqrstuvwxyz./") == strlen(argv[i]))
{
printf("%s - this string might contain digits, small letters and path symbols. It could be used for passing a file name or a path, for example.\n",argv[i]);
}
else if(strspn(argv[i], "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == strlen(argv[i]))
{
printf("The string \"%s\" contains only capital letters.\n",argv[i]);
}
}
}
评论
"-1"
""
scanf("%s",...)
./myprogram "" ''
argv[1]
argv[2]
if ( strlen(str) == strlen( itoa(atoi(str)) ) ) {
//its an integer
}
由于 atoi 将字符串转换为数字以外的数字跳跃字母,如果只有数字,则其字符串长度必须与原始字符串相同。 如果检查是针对整数的,则此解决方案比 innumber() 更好。
评论
char *array[4]; array[0] = (char*)malloc(10);
scanf("%s", array[0]);
strlen(array[0]) == strlen( itoa(atoi(array[0])) )
error: too few arguments to function 'itoa'
strcmp
"a"
#include "stdbool.h"
#include "stddef.h"
bool isNumber(char const* const text) {
if (text == NULL || text[0] == '\0') {
return false;
}
int dot_counter = 0;
size_t length = 1;
for (char character = text[1]; character != '\0';
++length, character = text[length]) {
bool const is_valid_character =
(character >= '0' && character <= '9') ||
(character == '.' && ++dot_counter == 1);
if (is_valid_character == false) {
return false;
}
}
char const first_character = text[0];
bool is_character_sign = (first_character == '-' || first_character == '+');
// verifications for first left character
if ((is_character_sign || first_character == '.') && length == 1) {
return false;
}
if (length == 2 && is_character_sign && text[1] == '.') {
return false;
}
return (is_character_sign || first_character == '.') ||
(first_character >= '0' && first_character <= '9');
}
#include <assert.h>
int main() {
char tmp[16];
assert(isNumber("a") == false);
assert(isNumber("aa") == false);
assert(isNumber("1"));
assert(isNumber("11"));
assert(isNumber("+1"));
assert(isNumber("+1.") && +1. == 1.0);
assert(isNumber("+.0") && +.0 == 0.0);
assert(isNumber("-1"));
assert(isNumber("-.0") && -.0 == -0.0);
assert(isNumber("-1.") && -1. == -1.0);
assert(isNumber("1.") && 1. == 1.0);
assert(isNumber(".0") && .0 == 0.0);
assert(isNumber(".") == false);
assert(isNumber("-") == false);
assert(isNumber("+") == false);
assert(isNumber("+.") == false);
assert(isNumber(".+") == false);
assert(isNumber("-.") == false);
assert(isNumber(".-") == false);
assert(isNumber("") == false);
assert(isNumber("1.1"));
assert(isNumber("-1.1"));
assert(isNumber("\0") == false);
assert(isNumber(NULL) == false);
return 0;
}
https://godbolt.org/z/YdnM6TKaz
评论
isNumber("-1")
true
isNumber("")
false
length
i
size_t
char character = text[length - 1];
length
0
重写整个函数,如下所示:
bool IsValidNumber(char * string)
{
for(int i = 0; i < strlen( string ); i ++)
{
//ASCII value of 0 = 48, 9 = 57. So if value is outside of numeric range then fail
//Checking for negative sign "-" could be added: ASCII value 45.
if (string[i] < 48 || string[i] > 57)
return FALSE;
}
return TRUE;
}
评论
48
'0'
strlen
IsValidNumber("-1")
true
IsValidNumber("")
false
问题在于您的代码“isDigit”的结果仅反映最后一个数字测试。据我了解,只要字符串中有任何字符不是数字,您就希望返回 isDigit = 0。按照你的逻辑,你应该像这样编码它:
char tmp[16];
scanf("%s", tmp);
int isDigit = 0;
int j=0;
isDigit = 1; /* Initialised it here */
while(j<strlen(tmp) && isDigit == 0){
if(tmp[j] > 57 || tmp[j] < 48) /* changed it to OR || */
isDigit = 0;
j++;
}
为了获得更易于理解的代码,我还会更改测试:
if(tmp[j] > 57 || tmp[j] < 48)
到以下内容:
if(tmp[j] > '9' || tmp[j] < '0')
评论
scanf("%s", tmp)
scanf("%15s", tmp)
&& isDigit == 0
-> && isDigit != 0
这些都不能适当地处理负数或浮点数。
怎么样:
bool
is_realnumber(char *instring) {
if (*instring != '-' && *instring != '.' && !isdigit(*instring)) return false;
if (strspn(instring+1, "0123456789.") < strlen(instring+1)) return false;
int c = 0;
while (*instring) if (*instring++ == '.') if (++c > 1) return false;
return true;
}
评论
is_realnumber("+1")
true
is_realnumber(".")
is_realnumber("-")
is_realnumber("-.")
false
我还可以扩展 Marcelo 支持浮点数的答案,如下所示:
char isnumber(const char *str)
{
int decpos = -1, pmpos = -1, engpos = strlen(str) - 1, epmpos = strlen(str) - 1;
for (int i = 0; i < strlen(str); i++)
/* check if it is integer */
if (str[i] > 47 && str[i] < 58)
continue;
/* check if it is decimal seperator and used once*/
else if (str[i] == 46 && decpos == -1)
{
decpos = i;
continue;
}
/* check if it is +/-, at the begining*/
else if ((str[i] == 43 || str[i] == 45) && i == 0)
{
pmpos = 1;
continue;
}
/* check if it is engineering format e/E, used once, after decimal and before +/-*/
else if ((str[i] == 69 || str[i] == 101) && engpos == strlen(str) - 1 && i > 0 && i > decpos && i < epmpos)
{
engpos = 1;
continue;
}
/* check if it is engineering format +/-, used once, after decimal and after engineering e/E*/
else if ((str[i] == 43 || str[i] == 45) && epmpos == strlen(str) - 1 && i > 0 && i > decpos && i > engpos)
{
epmpos = 1;
continue;
}
else
return 0;
return 1;
}
您可以按如下方式实现该函数:
bool isNumeric(const char* s){
while(*s){
if(*s < '0' || *s > '9')
return false;
++s;
}
return true;
}
评论
bool
isNumeric("")
true
isNumeric("-1")
true
可以通过 isdigit() 检查每个字符。
#include <string.h>
#include <ctype.h>
int is_digit_str(char* str){
int digit_count = 0;
for (int i = 0; i < strlen(str); i++) {
if(isdigit(str[i]))
digit_count++;
else
break;
}
return digit_count == strlen(str);
}
评论
is_digit_str("")
1
is_digit_str("-1")
1
如果您打算将来以整数/长格式使用该数字,您将调用或无论如何,在这种情况下,您可能只想检查返回值。atoi
atol
char tmp[16];
scanf("%s", tmp); // unsafe!!!
long tmp_long = atol(&tmp);
if (tmp_long == 0){
printf("%s: is not a number.\n", &tmp);
}
评论
"0"
int being_number(char string[]){
int l=strlen(string);
for (int i = 0; i < l; i++)
{
if(string[i] >= '0' && string[i] <= '9'){
i=i;
}
else{
return(0);
}
}
return(1);
}
评论
i=i;
?真?当然,你可以想到比这更不古怪的东西。
being_number("")
true
being_number("-1")
1
嗨,您可以使用此方法,它使用您从包含 ctype.h 库中获得的 isdigit() 函数。
这段代码检查 isdigit() 的返回值是否为零(这意味着我们正在分析的字符是非数字),如果是,则递增 j。
逻辑使用 j 变量作为“操作码”:如果不等于零,则它已递增,因此,函数会遇到非数字字符,否则字符串中存在的每个字符都是一个数字。
# include <stdio.h>
# include <ctype.h>
int main(int argc, char *argv[])
{
int i = 0;
int j = 0;
char data[] = "1234t6789";
int check;
while(data[i] != '\0'){
if((check = isdigit(data[i])) == 0)
j++;
i++;
}
if(j != 0)
printf("The string doesn't contain just numbers.\n");
else printf("The string contains only numbers.\n");
return 0;
}
这是最简单的答案:
bool isnumber(char string[]) {
int len = strlen(string);
int i = 0;
while (i < len)
{
if (isdigit(string[i]) == 0)
return false;
i++;
}
return true; }
评论
char
isdigit()
(unsigned char)
char
char
'+'
'-'
i
并且应该有类型,参数应该定义为 或 。len
size_t
string
const char string[]
const char *string
isnumber("")
true
char
<ctype.h>
下面是一个简单的自包含函数,用于验证字符串是否表示带有可选符号、至少一位数字和可选小数点的数字:
int isNumber(const char *str) {
size_t index = 0;
int has_digits = 0, has_dot = 0;
char cc;
// reject null pointer
if (!str) {
return 0;
}
// skip optional sign
if (*str == '+' || *str == '-') {
index++;
}
// scan the string
while ((cc = str[index++]) != '\0') {
if (cc == '.') {
// accept a single decimal point
if (has_dot++)
return 0;
} else
if (cc >= '0' && cc <= '9') {
// we have at least one digit
has_digits = 1;
} else {
// reject all other characters
return 0;
}
}
// must have at least one digit
return has_digits;
}
评论
scanf()
tmp