C ut缓冲区未读
如果您选择继续使用C ut缓冲区未读,c,file,readfile,C,File,Readfile,如果您选择继续使用scanf,则至少在stdin中可能存在未读字符时,使用简单函数手动清空输入缓冲区(stdin)。一个简单的函数就可以做到这一点。只需使用getchar()读取每个字符,直到遇到'\n'或EOF为止,例如 void empty_stdin (void) { int c = getchar(); while (c != '\n' && c != EOF) c = getchar(); } 注意:如果函数不带参数,则正确的声明包括
scanf
,则至少在stdin
中可能存在未读字符时,使用简单函数手动清空输入缓冲区(stdin
)。一个简单的函数就可以做到这一点。只需使用getchar()
读取每个字符,直到遇到'\n'
或EOF
为止,例如
void empty_stdin (void)
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
注意:如果函数不带参数,则正确的声明包括(void)
作为参数列表,以明确表示不需要参数
现在有了一种正确处理删除stdin中保留的字符的方法,您可以查看输入函数了
如果您使用getNumbers()
[1]和getMoreNumbers()
的目的是简单地从stdin
中读取一个整数,那么只需使用一个具有稍微更具描述性名称的函数即可完成此任务,例如:
int readintstdin (int *value) {
int rtn = 0;
printf ("Enter digits: ");
rtn = scanf ("%d", value); /* read 1 integer */
if (rtn == EOF)
fputs ("(user canceled input.)\n", stderr);
else if (rtn == 0)
fputs (" readintstdin() error: invalid input.\n", stderr);
empty_stdin(); /* remove all remaining chars from stdin */
return rtn;
}
注意:使用scanf
时,您负责处理三种情况:
EOF
来取消输入李>
stdin
,类似于:
int readintstdin (int *value) {
int rtn = 0;
printf ("Enter digits: ");
rtn = scanf ("%d", value); /* read 1 integer */
if (rtn == EOF)
fputs ("(user canceled input.)\n", stderr);
else if (rtn == 0)
fputs (" readintstdin() error: invalid input.\n", stderr);
empty_stdin(); /* remove all remaining chars from stdin */
return rtn;
}
case 2:
printf ("\n enter filename: "); /* get filename to read */
if (scanf ("%1023[^\n]", fname) != 1) {
fputs ("(user canceled input)\n", stderr);
empty_stdin();
break;
}
/* open/validate file open for reading */
if ((fp = fopen (fname, "r")) == NULL) {
perror ("fopen-fname");
empty_stdin();
break;
}
if (!readfromfile (fp)) /* read/output integers */
fprintf (stderr, "error: no values read from '%s'\n",
fname);
fclose (fp); /* close file */
break;
注意两件事,值的**地址作为参数传递,允许输入存储在该内存地址,并返回调用函数(main()
此处)而scanf
的返回值作为函数返回返回,指示main()
中的回读成功/失败。您必须始终使用适当的返回类型来创建函数,该返回类型将在调用函数中指示函数的成功或失败。否则,没有首先检查scanf
的返回也没有什么不同
您的下一个目标似乎是从“digits.txt”
读取所有值。由您决定,一般的方法是在调用者中打开文件*流
,在将文件流作为参数传递给函数之前,验证文件是否已打开以供读取。否则,如果打开失败,则无需调用函数开始,例如:
int readfromfile (FILE *fp) {
int value = 0, count = 0;
while (fscanf (fp, "%d", &value) == 1) { /* while valid int read */
printf ("%d ", value);
count++;
}
putchar ('\n'); /* tidy up with newline */
return count; /* return value indicating number of values read */
}
在这里,为了指示从文件读取的成功/失败,将返回从文件读取的值的数量。如果返回值为0
,则未从文件中读取任何值
接下来是菜单。您需要将这些相同的课程应用到菜单中。这意味着您需要处理scanf
的所有三种情况,并删除菜单每次显示之间stdin
中保留的所有字符。将这些保护措施落实到位后,您可以执行以下操作,例如:
#define MAXC 1024
...
int main (void) {
int input = 1, /* initialize all variables */
value = 0;
char fname[MAXC] = ""; /* buffer to hold filename to read */
FILE *fp = NULL;
while (0 < input && input < 3) {
int rtn = 0; /* store scanf return */
printf ("\nPlease select which method you'd like to access:\n"
" 1) readintstdin()\n"
" 2) readfromfile()\n"
" (any other numeric input exits)\n\n"
" choice: ");
rtn = scanf ("%d", &input);
if (rtn == EOF) { /* user generated manual EOF */
fputs ("(user canceled input)\n", stderr);
break;
}
else if (rtn == 0) { /* no integer input */
fputs (" error: invalid integer input.\n", stderr);
empty_stdin(); /* empty all chars from stdin */
continue; /* re-display menu, try again */
}
else /* good integer input */
empty_stdin(); /* empty all chars from stdin */
...
第二种情况需要更多的思考。您将从用户处获取文件名的输入(因此变量fname
在main()
开头的用途)。在这里,您只需提示并读取文件名(可能包含空格),验证读取内容,然后将文件名传递给fopen
以验证文件是否已打开以供读取。确认文件已打开以供读取后,只需将打开的文件流传递给函数(检查函数返回是否成功/失败),然后在完成后关闭文件。这可以类似于:
int readintstdin (int *value) {
int rtn = 0;
printf ("Enter digits: ");
rtn = scanf ("%d", value); /* read 1 integer */
if (rtn == EOF)
fputs ("(user canceled input.)\n", stderr);
else if (rtn == 0)
fputs (" readintstdin() error: invalid input.\n", stderr);
empty_stdin(); /* remove all remaining chars from stdin */
return rtn;
}
case 2:
printf ("\n enter filename: "); /* get filename to read */
if (scanf ("%1023[^\n]", fname) != 1) {
fputs ("(user canceled input)\n", stderr);
empty_stdin();
break;
}
/* open/validate file open for reading */
if ((fp = fopen (fname, "r")) == NULL) {
perror ("fopen-fname");
empty_stdin();
break;
}
if (!readfromfile (fp)) /* read/output integers */
fprintf (stderr, "error: no values read from '%s'\n",
fname);
fclose (fp); /* close file */
break;
注意:您的默认值:
案例应告知用户收到的值不在可接受的菜单值内,然后您可以指示程序已完成。(这只是一个小问题,你可以随意处理)
总而言之,您可以执行以下操作:
#include <stdio.h>
#define MAXC 1024
void empty_stdin (void)
{
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int readintstdin (int *value) {
int rtn = 0;
printf ("Enter digits: ");
rtn = scanf ("%d", value); /* read 1 integer */
if (rtn == EOF)
fputs ("(user canceled input.)\n", stderr);
else if (rtn == 0)
fputs (" readintstdin() error: invalid input.\n", stderr);
empty_stdin(); /* remove all remaining chars from stdin */
return rtn;
}
int readfromfile (FILE *fp) {
int value = 0, count = 0;
while (fscanf (fp, "%d", &value) == 1) { /* while valid int read */
printf ("%d ", value);
count++;
}
putchar ('\n'); /* tidy up with newline */
return count; /* return value indicating number of values read */
}
int main (void) {
int input = 1, /* initialize all variables */
value = 0;
char fname[MAXC] = "";
FILE *fp = NULL;
while (0 < input && input < 3) {
int rtn = 0; /* store scanf return */
printf ("\nPlease select which method you'd like to access:\n"
" 1) readintstdin()\n"
" 2) readfromfile()\n"
" (any other numeric input exits)\n\n"
" choice: ");
rtn = scanf ("%d", &input);
if (rtn == EOF) { /* user generated manual EOF */
fputs ("(user canceled input)\n", stderr);
break;
}
else if (rtn == 0) { /* no integer input */
fputs (" error: invalid integer input.\n", stderr);
empty_stdin(); /* empty all chars from stdin */
continue; /* re-display menu, try again */
}
else /* good integer input */
empty_stdin(); /* empty all chars from stdin */
switch (input) { /* switch on integer input */
case 1:
if (readintstdin (&value)) /* read from stdin */
printf ("value: %d\n", value);
break;
case 2:
printf ("\n enter filename: "); /* get filename to read */
if (scanf ("%1023[^\n]", fname) != 1) {
fputs ("(user canceled input)\n", stderr);
empty_stdin();
break;
}
/* open/validate file open for reading */
if ((fp = fopen (fname, "r")) == NULL) {
perror ("fopen-fname");
empty_stdin();
break;
}
if (!readfromfile (fp)) /* read/output integers */
fprintf (stderr, "error: no values read from '%s'\n",
fname);
fclose (fp); /* close file */
break;
default: /* handle invalid input */
fputs ("Selection not menu entry.\n", stderr);
break;
}
}
printf ("Program complete\n");
return 0;
}
希望这能解决您的大多数问题,并帮助您避免“因为我觉得这是一个简单的问题而感到压力。”确实如此,但C需要的理解深度远远超过“我会尝试这个,如果它不起作用,我会更改某些内容,重新编译并重试…”您可以控制整个机器,负责处理输入缓冲区的每个字节,并确保程序处理的每个字节都有足够的存储空间。C上没有训练轮。这就是它获得燃烧速度的地方。但是,“强大的力量带来巨大的责任”
脚注:
1。虽然不是错误,但C通常避免使用
camelCase
或MixedCase
变量名,而使用所有小写,同时保留大写名称以用于宏和常量。这是一个风格的问题——所以完全取决于你,但如果不遵循它,可能会在某些圈子里给人留下错误的第一印象。查看此链接,我想知道是否有香草c解决方案,而没有任何库。我不明白这个问题。你是在问如何设置变量吗?为此,请使用=
。作为第一步,不要对参数和全局变量使用相同的名称。请提供一个输入文件“digits.txt”“
的示例(如果太长,则为10行左右)。这将提供一种方法来衡量您迄今为止展示的方法是否合理。当然。每个人都需要不时举手。我们都是从同样的问题开始的。C不是你在一个月或一年内学会的东西。。。这更像是一次旅行,而不是一两个学期内所做的事情。学习C语言的关键就是放慢速度。阅读您使用的每个函数的手册页,慢慢地了解细节——有很多东西需要学习。但是没有比这更好的语言了。C将使你成为一个更好的程序员,不管你最终用什么语言编写。任何人都能学会一门语言,很少有人能学会编程。C是关于编程的。@frlzjosh如果
$ ./bin/menureadfilestdin
Please select which method you'd like to access:
1) readintstdin()
2) readfromfile()
(any other numeric input exits)
choice: 1
Enter digits: four-hundred twenty-one
readintstdin() error: invalid input.
Please select which method you'd like to access:
1) readintstdin()
2) readfromfile()
(any other numeric input exits)
choice: 1
Enter digits: 421
value: 421
Please select which method you'd like to access:
1) readintstdin()
2) readfromfile()
(any other numeric input exits)
choice: 2
enter filename: somefile.ext
fopen-fname: No such file or directory
Please select which method you'd like to access:
1) readintstdin()
2) readfromfile()
(any other numeric input exits)
choice: 2
enter filename: dat/digits.txt
1 10 299 1 200 15 3 150 13 2 150
Please select which method you'd like to access:
1) readintstdin()
2) readfromfile()
(any other numeric input exits)
choice: 1
Enter digits: 422
value: 422
Please select which method you'd like to access:
1) readintstdin()
2) readfromfile()
(any other numeric input exits)
choice: (user canceled input)
Program complete