C 中清除缓冲区的问题
Issue with clearing buffer in C
我正在尝试从键盘读取一些字符串并将它们保存到数组中。我指定了要读取的最大字符数并在中间首字母后清除缓冲区以丢弃所有字符并超出限制。一旦我输入超过最大字符数,一切似乎都很好。但是,如果我输入的少于最大值怎么办?我得到了额外的空行。好像程序在等待输入,我不知道为什么。有人可以阐明我知识的这个影子吗?
这是我的代码片段
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char name[35];
char middlename[7];
char lastname[35];
printf("Please enter name: ");
scanf("%34[^\n]%*c", name);
printf("Please enter middle name: ");
scanf("%6[^\n]%*c", middlename);
while (getchar() != '\n');
printf("Please enter last name: ");
scanf("%34[^\n]%*c", lastname);
}
这是我的输出:
Please enter name: Antony
Please enter middle name: Jr.
_ // here it waits for input
每次调用scanf都是这样
scanf("%34[^\n]%*c", name);
删除第二个转换说明符
scanf("%34[^\n]", name);
而不是使用循环
while (getchar() != '\n');
否则例如在这段代码中
scanf("%6[^\n]%*c", middlename);
while (getchar() != '\n');
您正在尝试读取换行符 '\n'
两次。
另一种方法如下
printf("Please enter name: ");
scanf("%34[^\n]%*[^\n]", name);
printf("Please enter middle name: ");
scanf(" %6[^\n]%*[^\n]", middlename);
printf("Please enter last name: ");
scanf(" %34[^\n]*[^\n]", lastname);
注意第一个格式说明符之前的第二次和第三次 scanf 调用中的空白。
一位同事在页面上方正确解释了所有内容。修饰符 ( * ) - 抑制下一个说明符的输入是个好主意,但不适用于这种情况。您的代码与自身略有冲突。这样做,程序就会运行良好。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void)
{
char name[35];
char middlename[7];
char lastname[35];
printf("Please enter name: ");
scanf(" %34[^\n]", name);
printf("Please enter middle name: ");
while (getchar() != '\n');
scanf(" %6[^\n]", middlename);
printf("Please enter last name: ");
while (getchar() != '\n');
scanf(" %34[^\n]", lastname);
while (getchar() != '\n');
//Development of events
return 0;
}
可以使用另一个函数来使用 fgetc
进行输入。
只要有空间就填满数组。
读取并丢弃多余的字符。这会向用户报告。可以丢弃整个输入,要求用户重试。
#include <stdio.h>
#include <string.h>
int fgetcstr ( char *input, size_t size, FILE *fin) {
int c = 0;
int used = 0;
int extra = 0;
while( EOF != ( c = fgetc ( fin))) {//read until end of file
if ( c == '\n') {
break;//stop on newline
}
if ( used < size - ( size > 1)) {
input[used] = c;//store character
used++;//increment for next character
if ( size > 1) {
input[used] = 0;//zero terminate
}
}
else {
++extra;
}
}
if ( EOF == c && 0 == used) {//end of file and no characters read
return EOF;
}
if ( extra) {
printf ( "entered %d characters. only %zu allowed.\n\tExtra DISCARDED\n"
, extra + used, size - ( size > 1));
extra = 0;
used = 0;
}
return 1;
}
int main ( void) {
char name[35] = "";
char middlename[7] = "";
char lastname[35] = "";
printf("Please enter name: ");
fflush ( stdout);
if ( EOF == fgetcstr ( name, sizeof name, stdin)) {
fprintf ( stderr, "EOF\n");
return 0;
}
printf("Please enter middle name: ");
fflush ( stdout);
if ( EOF == fgetcstr ( middlename, sizeof middlename, stdin)) {
fprintf ( stderr, "EOF\n");
return 0;
}
printf("Please enter last name: ");
fflush ( stdout);
if ( EOF == fgetcstr ( lastname, sizeof lastname, stdin)) {
fprintf ( stderr, "EOF\n");
return 0;
}
printf ( "name: %s\n", name);
printf ( "middlename: %s\n", middlename);
printf ( "lastname: %s\n", lastname);
return 0;
}
我正在尝试从键盘读取一些字符串并将它们保存到数组中。我指定了要读取的最大字符数并在中间首字母后清除缓冲区以丢弃所有字符并超出限制。一旦我输入超过最大字符数,一切似乎都很好。但是,如果我输入的少于最大值怎么办?我得到了额外的空行。好像程序在等待输入,我不知道为什么。有人可以阐明我知识的这个影子吗?
这是我的代码片段
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char name[35];
char middlename[7];
char lastname[35];
printf("Please enter name: ");
scanf("%34[^\n]%*c", name);
printf("Please enter middle name: ");
scanf("%6[^\n]%*c", middlename);
while (getchar() != '\n');
printf("Please enter last name: ");
scanf("%34[^\n]%*c", lastname);
}
这是我的输出:
Please enter name: Antony
Please enter middle name: Jr.
_ // here it waits for input
每次调用scanf都是这样
scanf("%34[^\n]%*c", name);
删除第二个转换说明符
scanf("%34[^\n]", name);
而不是使用循环
while (getchar() != '\n');
否则例如在这段代码中
scanf("%6[^\n]%*c", middlename);
while (getchar() != '\n');
您正在尝试读取换行符 '\n'
两次。
另一种方法如下
printf("Please enter name: ");
scanf("%34[^\n]%*[^\n]", name);
printf("Please enter middle name: ");
scanf(" %6[^\n]%*[^\n]", middlename);
printf("Please enter last name: ");
scanf(" %34[^\n]*[^\n]", lastname);
注意第一个格式说明符之前的第二次和第三次 scanf 调用中的空白。
一位同事在页面上方正确解释了所有内容。修饰符 ( * ) - 抑制下一个说明符的输入是个好主意,但不适用于这种情况。您的代码与自身略有冲突。这样做,程序就会运行良好。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void)
{
char name[35];
char middlename[7];
char lastname[35];
printf("Please enter name: ");
scanf(" %34[^\n]", name);
printf("Please enter middle name: ");
while (getchar() != '\n');
scanf(" %6[^\n]", middlename);
printf("Please enter last name: ");
while (getchar() != '\n');
scanf(" %34[^\n]", lastname);
while (getchar() != '\n');
//Development of events
return 0;
}
可以使用另一个函数来使用 fgetc
进行输入。
只要有空间就填满数组。
读取并丢弃多余的字符。这会向用户报告。可以丢弃整个输入,要求用户重试。
#include <stdio.h>
#include <string.h>
int fgetcstr ( char *input, size_t size, FILE *fin) {
int c = 0;
int used = 0;
int extra = 0;
while( EOF != ( c = fgetc ( fin))) {//read until end of file
if ( c == '\n') {
break;//stop on newline
}
if ( used < size - ( size > 1)) {
input[used] = c;//store character
used++;//increment for next character
if ( size > 1) {
input[used] = 0;//zero terminate
}
}
else {
++extra;
}
}
if ( EOF == c && 0 == used) {//end of file and no characters read
return EOF;
}
if ( extra) {
printf ( "entered %d characters. only %zu allowed.\n\tExtra DISCARDED\n"
, extra + used, size - ( size > 1));
extra = 0;
used = 0;
}
return 1;
}
int main ( void) {
char name[35] = "";
char middlename[7] = "";
char lastname[35] = "";
printf("Please enter name: ");
fflush ( stdout);
if ( EOF == fgetcstr ( name, sizeof name, stdin)) {
fprintf ( stderr, "EOF\n");
return 0;
}
printf("Please enter middle name: ");
fflush ( stdout);
if ( EOF == fgetcstr ( middlename, sizeof middlename, stdin)) {
fprintf ( stderr, "EOF\n");
return 0;
}
printf("Please enter last name: ");
fflush ( stdout);
if ( EOF == fgetcstr ( lastname, sizeof lastname, stdin)) {
fprintf ( stderr, "EOF\n");
return 0;
}
printf ( "name: %s\n", name);
printf ( "middlename: %s\n", middlename);
printf ( "lastname: %s\n", lastname);
return 0;
}