C语言如何保证char值非负 输入-1时for循环无法break怎么办
故障原因
- 现有代码的输入判断逻辑完全错位:你输入的
-1会被scanf("%d", &placeholder)读到placeholder变量里,根本不会存入name数组,因此判断staff[i].name[0] == -1的逻辑永远不可能触发。 scanf("%d")读取整数后会把输入缓冲区中的换行符留在队列中,后续fgets会直接读取到这个空换行,连正常的姓名输入流程都会出问题。- C语言标准未规定原生
char类型的符号性,不同编译器、编译选项下char可能默认是有符号类型,存在取负值的可能。
修正实现代码
#include <stdio.h> #include <string.h> #include <stdlib.h> struct employee{ unsigned char name[30]; // 显式指定无符号字符类型,避免取值为负 float rate; float hrsWorked; }; int main() { struct employee staff[5]; unsigned char input_buf[30]; char *endptr; int valid_count = 0; for(int i = 0; i < 5; i++){ printf("Enter name (input -1 to terminate): "); // 直接读取整行输入,避免scanf残留换行导致的输入异常 fgets(input_buf, sizeof(input_buf), stdin); // 清理fgets读取到的行尾换行符 size_t input_len = strlen(input_buf); if (input_len > 0 && input_buf[input_len-1] == '\n') { input_buf[input_len-1] = '\0'; input_len--; } // 判断输入是否为终止指令-1 long input_val = strtol(input_buf, &endptr, 10); if (*endptr == '\0' && input_val == -1) { break; } // 校验姓名长度,避免数组越界后存入结构体 size_t copy_len = input_len < sizeof(staff[i].name)-1 ? input_len : sizeof(staff[i].name)-1; memcpy(staff[i].name, input_buf, copy_len); staff[i].name[copy_len] = '\0'; valid_count++; // 后续可在这里补充rate、hrsWorked字段的读取逻辑 } printf("Loop terminated, total %d valid employee records entered\n", valid_count); return 0; }
关键修正说明
- 废弃逻辑错位的
scanf占位读入写法,全程用fgets读取整行输入,从根源避免缓冲区残留换行导致的输入异常。 - 终止判断直接解析整行输入内容:仅当用户输入的整行内容为纯
-1时触发循环终止,不会和正常姓名输入(比如名字里带-1前缀的内容)产生冲突。 - 姓名字段显式使用
unsigned char类型定义,从类型层面保证存储的字符取值范围为0~255,不存在负数取值,无需额外做值校验。 - 补充了输入换行清理、字符串长度校验逻辑,避免字符串拷贝时出现数组越界问题。
内容的提问来源于stack exchange,提问作者Fuss
相关产品推荐
相关产品推荐

