为什么我必须为输入的每个字符串按两次回车键?
why do I have to press enter twice for each string I enter?
这是代码:
void inserisciStringa(int dim, char *i) {
int men = 1;
do {
if (scanf("%[^\n]s", i) == 1) {
svuotaBuffer(); // I think this is the problem
int len = checkStrLen(men, dim, i);
int num = checkNumbers(len, i);
if (len && num)
break;
}
printf("\nError");
printf("\nTry again: ");
} while (1);
}
int checkStrLen(int min, int max, char *s) {
int len = strlen(s);
if (len >= min && len <= max)
return len;
else
return 0;
}
int checkNumbers(int len, char *s) {
int i;
for (i = 0; i < len; i++) {
if (s[i] >= '0' && s[i] <= '9') {
printf("\nNot Numbers");
return 0;
}
}
}
void svuotaBuffer() {
char c;
do {
c = getchar();
} while(c != '\n');
}
每次我必须插入一个字符串时,由于svuotaBuffer()
,我不得不按两次回车键。
但是如果我删除它,我就会有无限循环。
我能以某种方式修复它吗?我注意到它并不总是这样做,但这是一个非常烦人的问题
这个:
int men=1;
do {
if (scanf("%[^\n]s", i) == 1) {
svuotaBuffer(); //I think this is the problem
int len = checkStrLen(men, dim, i);
int num = checkNumbers(len,i);
if (len && num) break;
}
printf("\nError");
printf("\nTry again: ");
} while(1);
可以用更简单的方式实现,例如,允许您消除 svuotaBuffer
,等等。其他:
....
char line[80] = {0};
int num = 0, len = 0;
fgets(line, sizeof(line), stdin);
while(line[0] != '\n'))
{
line[strcspn(line, "\n")] = 0;//eliminate newline
len = strlen(line);//check line length
num = checkNumbers(len,i);
//do other things, i.e. parse and/or store line in output file, ...?
fgets(line, sizeof(line), stdin);
}
....
问题来自scanf()
,一个非常棘手的函数:
- 首先格式字符串
"%[^\n]s"
不正确,它应该只是 "%[^\n]"
因为尾随 s
与 %s
不同,这意味着匹配一个 s
在输入流中,这不会在那里发生,因为上一次转换后唯一的未决字符是 \n
或文件结尾。
- 您的转换是有风险的,因为您无法告诉
scanf()
要将多少字符存储到目标数组中。任何足够长的输入行都会导致未定义的行为。
- 转换成功后,换行符将保留在输入流中。在尝试使用
scanf()
读取下一行之前,必须读取此换行符。否则 scanf()
将失败,因为 %[^\n]
无法转换空字符串。
- 在转换失败后,即第二次发生的情况,还必须调用
svuotaBuffer()
以删除挂起的换行符。
还要注意这些问题:
svuotaBuffer()
也有一个问题:c
应该有类型 int
并且你必须检查 EOF
以避免最后的无限循环的文件。这是更正后的版本:
int svuotaBuffer(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c; // allow the caller to test for end-of-file.
}
如果循环完成,函数 checkNumbers
应该 return 1
。
给一个 char *
i
.
命名 非常混乱
这是修改后的版本:
int checkStrLen(int min, int max, char *s) {
int len = strlen(s);
if (len >= min && len <= max)
return len;
else
return 0;
}
int checkNumbers(int len, char *s) {
int i;
for (i = 0; i < len; i++) {
if (s[i] >= '0' && s[i] <= '9') {
printf("\nNot Numbers");
return 0;
}
}
return 1;
}
int svuotaBuffer(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c; // allow the caller to test for end-of-file.
}
int inserisciStringa(int dim, char *dest) {
int men = 1;
for (;;) {
if (scanf("%[^\n]", dest) == 1) {
svuotaBuffer(); // read the ending newline if any
if (checkStrLen(men, dim, dest) && checkNumbers(len, dest))
return 0;
}
if (svuotaBuffer() == EOF) {
printf("\nUnexpected end of file\n");
return -1; // report failure to the caller.
}
printf("\nError");
printf("\nTry again: ");
}
}
你真的应该使用 fgets()
来完成这个任务。这是修改后的版本:
int inserisciStringa(int dim, char *dest) {
int men = 1;
int len;
for (;;) {
if (!fgets(dest, dim, stdin)) {
printf("\nUnexpected end of file\n");
return -1; // report end of file failure to the caller.
}
len = strlen(dest);
if (len > 0 && dest[len - 1] == '\n')
dest[--len] == '[=12=]'; // strip the trailing newline
if (len < men) {
printf("\nError: line too short");
} else
if (len < dim - 1) {
if (checkNumbers(len, dest))
return 0;
printf("\nError: string has digits");
} else {
printf("\nError: line too long");
svuotaBuffer();
}
printf("\nTry again: ");
}
}
这是代码:
void inserisciStringa(int dim, char *i) {
int men = 1;
do {
if (scanf("%[^\n]s", i) == 1) {
svuotaBuffer(); // I think this is the problem
int len = checkStrLen(men, dim, i);
int num = checkNumbers(len, i);
if (len && num)
break;
}
printf("\nError");
printf("\nTry again: ");
} while (1);
}
int checkStrLen(int min, int max, char *s) {
int len = strlen(s);
if (len >= min && len <= max)
return len;
else
return 0;
}
int checkNumbers(int len, char *s) {
int i;
for (i = 0; i < len; i++) {
if (s[i] >= '0' && s[i] <= '9') {
printf("\nNot Numbers");
return 0;
}
}
}
void svuotaBuffer() {
char c;
do {
c = getchar();
} while(c != '\n');
}
每次我必须插入一个字符串时,由于svuotaBuffer()
,我不得不按两次回车键。
但是如果我删除它,我就会有无限循环。
我能以某种方式修复它吗?我注意到它并不总是这样做,但这是一个非常烦人的问题
这个:
int men=1;
do {
if (scanf("%[^\n]s", i) == 1) {
svuotaBuffer(); //I think this is the problem
int len = checkStrLen(men, dim, i);
int num = checkNumbers(len,i);
if (len && num) break;
}
printf("\nError");
printf("\nTry again: ");
} while(1);
可以用更简单的方式实现,例如,允许您消除 svuotaBuffer
,等等。其他:
....
char line[80] = {0};
int num = 0, len = 0;
fgets(line, sizeof(line), stdin);
while(line[0] != '\n'))
{
line[strcspn(line, "\n")] = 0;//eliminate newline
len = strlen(line);//check line length
num = checkNumbers(len,i);
//do other things, i.e. parse and/or store line in output file, ...?
fgets(line, sizeof(line), stdin);
}
....
问题来自scanf()
,一个非常棘手的函数:
- 首先格式字符串
"%[^\n]s"
不正确,它应该只是"%[^\n]"
因为尾随s
与%s
不同,这意味着匹配一个s
在输入流中,这不会在那里发生,因为上一次转换后唯一的未决字符是\n
或文件结尾。 - 您的转换是有风险的,因为您无法告诉
scanf()
要将多少字符存储到目标数组中。任何足够长的输入行都会导致未定义的行为。 - 转换成功后,换行符将保留在输入流中。在尝试使用
scanf()
读取下一行之前,必须读取此换行符。否则scanf()
将失败,因为%[^\n]
无法转换空字符串。 - 在转换失败后,即第二次发生的情况,还必须调用
svuotaBuffer()
以删除挂起的换行符。
还要注意这些问题:
svuotaBuffer()
也有一个问题:c
应该有类型int
并且你必须检查EOF
以避免最后的无限循环的文件。这是更正后的版本:int svuotaBuffer(void) { int c; while ((c = getchar()) != EOF && c != '\n') continue; return c; // allow the caller to test for end-of-file. }
如果循环完成,函数
checkNumbers
应该 return1
。给一个
命名 非常混乱char *
i
.
这是修改后的版本:
int checkStrLen(int min, int max, char *s) {
int len = strlen(s);
if (len >= min && len <= max)
return len;
else
return 0;
}
int checkNumbers(int len, char *s) {
int i;
for (i = 0; i < len; i++) {
if (s[i] >= '0' && s[i] <= '9') {
printf("\nNot Numbers");
return 0;
}
}
return 1;
}
int svuotaBuffer(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c; // allow the caller to test for end-of-file.
}
int inserisciStringa(int dim, char *dest) {
int men = 1;
for (;;) {
if (scanf("%[^\n]", dest) == 1) {
svuotaBuffer(); // read the ending newline if any
if (checkStrLen(men, dim, dest) && checkNumbers(len, dest))
return 0;
}
if (svuotaBuffer() == EOF) {
printf("\nUnexpected end of file\n");
return -1; // report failure to the caller.
}
printf("\nError");
printf("\nTry again: ");
}
}
你真的应该使用 fgets()
来完成这个任务。这是修改后的版本:
int inserisciStringa(int dim, char *dest) {
int men = 1;
int len;
for (;;) {
if (!fgets(dest, dim, stdin)) {
printf("\nUnexpected end of file\n");
return -1; // report end of file failure to the caller.
}
len = strlen(dest);
if (len > 0 && dest[len - 1] == '\n')
dest[--len] == '[=12=]'; // strip the trailing newline
if (len < men) {
printf("\nError: line too short");
} else
if (len < dim - 1) {
if (checkNumbers(len, dest))
return 0;
printf("\nError: string has digits");
} else {
printf("\nError: line too long");
svuotaBuffer();
}
printf("\nTry again: ");
}
}