c语言中的getchar()函数
我刚从stephen Kochan的c编程开始学习c中的I/O文件操作。在下面的一个练习问题中 编写一个程序,在终端一次显示20行文件内容。在每20行的末尾,让程序等待从终端输入字符。如果字符是字母q,程序应停止显示文件;任何其他字符都会导致显示文件中接下来的20行 因此,c语言中的getchar()函数,c,file,scanf,getchar,C,File,Scanf,Getchar,我刚从stephen Kochan的c编程开始学习c中的I/O文件操作。在下面的一个练习问题中 编写一个程序,在终端一次显示20行文件内容。在每20行的末尾,让程序等待从终端输入字符。如果字符是字母q,程序应停止显示文件;任何其他字符都会导致显示文件中接下来的20行 因此,getchar()第一次没有提示输入。因此,我将getchar()所在的部分替换为: scanf(" %c",&again); 正如预期的那样,它工作得很好。程序在20行新行之后第一次提示输入。我还留下了一些空白,以
getchar()
第一次没有提示输入。因此,我将getchar()
所在的部分替换为:
scanf(" %c",&again);
正如预期的那样,它工作得很好。程序在20行新行之后第一次提示输入。我还留下了一些空白,以便scanf
可以忽略它。由于篇幅太长,我想我还没有完全理解getchar()
的行为。我自己也在努力学习这些东西,我在谷歌上搜索了一个解释,但结果一无所获。如果您对此有任何帮助和反馈,我们将不胜感激
scanf("%s",name);
当您在程序中到达这一点并键入文件名并按enter键后,一个换行字符(\n
)将添加到输入流中,该字符不是由scanf
读取的,而是由第一次调用getchar()
提取的
使用scanf
读取文件名的另一个问题是,用空格处理文件名很麻烦。考虑使用<代码> fgScript()< /C> >,这将既读取直线进给字符,又处理空格文件名。使用fgets()
的缺点是您必须自己去除\n
字符
#include <string.h>
// ...
char name[64];
if (fgets(name, sizeof name, stdin) != NULL)
{
// strip the linefeed character off
size_t len = strlen(name);
if (len > 0 && name[len - 1] == '\n')
name[len - 1] = '\0';
}
else
{
// if fgets returns NULL then an error with the input occurred
}
当您在程序中到达这一点并键入文件名并按enter键后,一个换行字符(\n
)将添加到输入流中,该字符不是由scanf
读取的,而是由第一次调用getchar()
提取的
使用scanf
读取文件名的另一个问题是,用空格处理文件名很麻烦。考虑使用<代码> fgScript()< /C> >,这将既读取直线进给字符,又处理空格文件名。使用fgets()
的缺点是您必须自己去除\n
字符
#include <string.h>
// ...
char name[64];
if (fgets(name, sizeof name, stdin) != NULL)
{
// strip the linefeed character off
size_t len = strlen(name);
if (len > 0 && name[len - 1] == '\n')
name[len - 1] = '\0';
}
else
{
// if fgets returns NULL then an error with the input occurred
}
您遇到的问题是,大多数使用
scanf
且不考虑输入缓冲区中所有字符(例如stdin
)的新C程序员都会遇到。当您使用%s
作为格式说明符调用scanf
时,键入input,然后按Enter键,直到第一个空格字符为止的所有内容都将读取到参数列表中指定的指针变量中--在stdin
中保留未读取的'\n'
(即空格)。下次尝试从stdin
读取时,首先读取的是上次调用scanf
后的'\n'
。如果您正在使用从stdin
读取的内容不能处理'\n'
-您有问题
要正确处理此问题,请在每次调用scanf
时以格式字符串说明换行符,或使用getchar()
循环stdin
,直到遇到'\n'
(或EOF
)为止。使用格式字符串,您可以使用:
scanf("%s%*c",name); /* you should check the return == 1 */
或在字符串中允许空格
scanf("%[^\n]%*c",name); /* ditto */
如果%[^\n]
读取所有字符,但不包括换行符(允许字符串中有空格),并且%*c
读取并丢弃'\n'
而不添加匹配计数('*'
作为赋值抑制运算符),则还应添加%63[^\n]
限制读取的字符数,以防止写入超出数组边界
但是,如果练习的目的是熟悉面向字符的输入函数(getchar
,fgetc
,等等),那么为什么要从这些函数开始呢?您可以简单地执行以下操作:
enum { MAXL = 20, MAXC = 256 };
...
FILE *fp = argc > 1 ? fopen (argv[1], "r") : NULL;
if (!fp) {
char fname[MAXC] = "";
char *p = fname;
int n = 0;
printf ("\nenter a filename: ");
while (n + 1 < MAXC && (c = getchar()) != '\n' && c != EOF) *p++ = c, n++;
*p = 0;
fp = fopen (fname, "r");
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
}
#include <stdio.h>
enum { MAXL = 20, MAXC = 256 };
int main (int argc, char **argv) {
int c, idx = 0, pgsz = MAXL, line = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : NULL;
if (!fp) {
char fname[MAXC] = "";
char *p = fname;
int n = 0;
printf ("\nenter a filename: ");
while (n+1 < MAXC && (c = getchar()) != '\n' && c != EOF) *p++ = c, n++;
*p = 0;
fp = fopen (fname, "r");
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
}
while ((c = fgetc (fp)) != EOF) {
if (c == '\n') idx++;
if (idx == pgsz) {
line += pgsz;
printf ("\n__ line %d, quit (q)? ", line);
int ch;
if ((ch = getchar()) == 'q') break;
while ((ch = getchar() != '\n' && ch != EOF)) {}
idx = 0;
}
else
putchar (c);
}
if (fp != stdin) fclose (fp);
return 0;
}
如果您有任何问题,请仔细查看并告诉我。您遇到的问题是大多数使用
scanf
的新C程序员都会遇到的问题,他们无法解释输入缓冲区中的所有字符(例如stdin
)。当您使用%s
作为格式说明符调用scanf
时,键入input,然后按Enter键,直到第一个空格字符为止的所有内容都将读取到参数列表中指定的指针变量中--在stdin
中保留未读取的'\n'
(即空格)。下次尝试从stdin
读取时,首先读取的是上次调用scanf
后的'\n'
。如果您正在使用从stdin
读取的内容不能处理'\n'
-您有问题
要正确处理此问题,请在每次调用scanf
时以格式字符串说明换行符,或使用getchar()
循环stdin
,直到遇到'\n'
(或EOF
)为止。使用格式字符串,您可以使用:
scanf("%s%*c",name); /* you should check the return == 1 */
或在字符串中允许空格
scanf("%[^\n]%*c",name); /* ditto */
如果%[^\n]
读取所有字符,但不包括换行符(允许字符串中有空格),并且%*c
读取并丢弃'\n'
而不添加匹配计数('*'
作为赋值抑制运算符),则还应添加%63[^\n]
限制读取的字符数,以防止写入超出数组边界
但是如果练习的目的是熟悉面向字符的输入函数(getchar
,fgetc$ ./bin/pager
enter a filename: ../dat/100int.txt
27086
29317
...
29927
24511
__ line 20, quit (q)? q
#include<stdio.h>
int main(void)
{
int count=0,c;
FILE *fname;
char name[64];
char again='a';
printf("enter the name of file to be read : ");
scanf("%s",name);
getchar();
if((fname=fopen(name,"r"))==NULL){
printf("file %s cannot be opened for reading \n",name);
return 1;
}
while(again!='q'){
count=0;
while((c=getc(fname))!=EOF)
{
if(c!='\n')
{
putchar(c);
}
else{
putchar('\n');
count++;
printf("count = %i\n",count); //debug statement
}
if(count>19)
break;
}
again=getchar();
printf("again = %c\n",again); //debug statement
}
fclose(fname);
printf("\n");
return 0;
}