[英]Validating input is of certain length in C
我的程序要求用户输入由 16 个字符组成的输入(不包括 null 终止符),然后将其存储在单独的字符串中。 这是我当前的代码:
void takeInput16(char *inputStr, int size){
do{
printf("Enter a string of length 16\n");
fgets(inputStr, size, stdin);
} while(!(inputStr[size - 2] == '\n' && inputStr[size - 3] != '\0'));
}
int main(){
char *num1 = malloc(18 * sizeof(char));
char *num2 = malloc(18 * sizeof(char));
takeInput16(num1, 18);
takeInput16(num2, 18);
return 0;
}
这适用于检测少于 16 个字符的输入,但是它不能处理超过 16 个字符的输入,因为它会导致多次调用 fgets。
我的问题是,我怎样才能安全地输入 C 并确保它在字符方面具有一定的大小(我想拒绝输入太长而不是简单地截断多余的字符)
假设输入是 ASCII,您可以使用fgetc
逐个读取字符,直到缓冲区已满或检测到\n
。 如果缓冲区已满,请继续读取直到检测到\n
,如下例所示。
请注意,当 size 为 5 时,此示例将读取最多 4 个字符,它需要为结尾处的空终止字符留出空间。 stdin
不需要EOF
检查,但您最好将其放在那里,以防输入被重定向。
int takeInputx(char* buf, int bufsize)
{
buf[bufsize - 1] = '\0';
for (int i = 0; ; i++)
{
int ch = fgetc(stdin);
int end = (ch == '\n' || ch == EOF);
if (i < bufsize - 1)
buf[i] = end ? '\0' : (char)ch;
if (end)
return i;
}
return 0;
}
int main()
{
int size = 5;
char* num1 = malloc(size * sizeof(char));
for (int i = 0; i < 3; i++)
{
int res = takeInputx(num1, size);
printf("%s, string len %d, exceeds max size? %d\n",
num1, strlen(num1), res >= size);
}
free(num1);
return 0;
}
您的代码未正确检查输入: null 字节应为偏移size - 1
和换行符为偏移size - 2
,但最重要的是您应该检查fgets()
没有失败并且输入的长度是size - 1
。
这是修改后的版本:
#include <stdio.h>
#include <string.h>
void takeInput(char *inputStr, int size) {
for (;;) {
printf("Enter a string of length %d\n", size - 2);
if (!fgets(inputStr, size, stdin)) {
perror("input error");
abort();
}
if (strlen(inputStr) < size - 1) {
printf("input too short, need %d bytes\n", size - 2);
continue;
}
if (inputStr[size - 2] != '\n') {
int c;
/* read and discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("input too long, need %d bytes\n", size - 2);
continue;
}
inputStr[size - 2] = '\0'; /* strip the newline */
break;
}
}
int main() {
char *num1 = malloc(18 * sizeof(char));
char *num2 = malloc(18 * sizeof(char));
takeInput(num1, 18);
takeInput(num2, 18);
printf("num1: %s\n", num1);
printf("num2: %s\n", num2);
free(num1);
free(num2);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.