如何将char数组适配isdigit()以识别输入的数值或字符串类型
现有代码问题修复
isdigit函数要求传入单个字符的unsigned char类型值(或EOF),你直接传入数组名userInput(本质是字符指针)肯定无法得到正确结果,需要改为取数组的单个元素userInput[i],且强制转换为unsigned char避免有符号字符的负值触发未定义行为fgets会将输入末尾的换行符\n一同存入数组,会干扰后续类型判断,需要先把换行符替换为字符串结束符\0
完整实现逻辑
判断逻辑如下:
- 预处理输入,移除末尾换行符
- 遍历整个输入串,校验是否符合数字格式规则:
- 首字符允许为
+/-/数字/小数点,其余位置只能是数字或小数点 - 整个串中小数点的数量最多为1
- 不能仅存在符号位,不能仅存在小数点,小数点前后不能同时为空
- 首字符允许为
- 符合数字格式的,再根据有没有小数点、首字符是否为负号判断属于正/负整数、正/负小数,否则判定为字符串
示例代码
#include <stdio.h> #include <string.h> #include <ctype.h> void input() { char userInput[500]; printf("Enter something: "); if (fgets(userInput, 500, stdin) == NULL) { return; } // 移除fgets读入的末尾换行符 userInput[strcspn(userInput, "\n")] = '\0'; int len = strlen(userInput); if (len == 0) { printf("输入为空\n"); return; } int has_dot = 0; int is_number = 1; // 首字符判断 if (userInput[0] != '+' && userInput[0] != '-' && !isdigit((unsigned char)userInput[0]) && userInput[0] != '.') { is_number = 0; } if (userInput[0] == '.') { has_dot = 1; } // 遍历剩余字符 for (int i = 1; i < len; i++) { if (userInput[i] == '.') { if (has_dot) { // 已经存在一个小数点 is_number = 0; break; } has_dot = 1; } else if (!isdigit((unsigned char)userInput[i])) { is_number = 0; break; } } // 校验数字合法性,排除只有符号、只有小数点的无效情况 if (is_number) { int has_digit = 0; for (int i = 0; i < len; i++) { if (isdigit((unsigned char)userInput[i])) { has_digit = 1; break; } } if (!has_digit) { is_number = 0; } } // 输出分类结果 if (!is_number) { printf("输入类型:字符串\n"); } else { int is_negative = (userInput[0] == '-'); if (has_dot) { printf("输入类型:%s小数\n", is_negative ? "负" : "正"); } else { printf("输入类型:%s整数\n", is_negative ? "负" : "正"); } } }
内容的提问来源于stack exchange,提问作者ExaltedCaricature
相关产品推荐
相关产品推荐

