Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c语言中的getchar()函数_C_File_Scanf_Getchar - Fatal编程技术网

c语言中的getchar()函数

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行新行之后第一次提示输入。我还留下了一些空白,以

我刚从stephen Kochan的c编程开始学习c中的I/O文件操作。在下面的一个练习问题中

编写一个程序,在终端一次显示20行文件内容。在每20行的末尾,让程序等待从终端输入字符。如果字符是字母q,程序应停止显示文件;任何其他字符都会导致显示文件中接下来的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;
}