如何在C中从标准输入中读取多行字符串?

如何在C中从标准输入中读取多行字符串?,c,scanf,stdin,C,Scanf,Stdin,我是C编程的新手。假设我想从stdin读取多行字符串。我怎样才能一直读到只包含EOL的一行 输入示例 1+2\n 1+2+3\n 1+2+3+4\n \n (stop at this line) 似乎当我直接点击enter(EOL)时,scanf将不会执行,直到输入了除EOL以外的内容。我怎样才能解决这个问题 如果有人能帮我,我会非常感激的。谢谢。如果你想学习C,你应该避免scanf。只有在C语言错误的情况下,scanf才有意义。花在学习scanf的缺点上的时间并没有花得很好,它也没有真正教会

我是C编程的新手。假设我想从stdin读取多行字符串。我怎样才能一直读到只包含EOL的一行

输入示例

1+2\n
1+2+3\n
1+2+3+4\n
\n (stop at this line)
似乎当我直接点击enter(EOL)时,scanf将不会执行,直到输入了除EOL以外的内容。我怎样才能解决这个问题


如果有人能帮我,我会非常感激的。谢谢。

如果你想学习C,你应该避免
scanf
。只有在C语言错误的情况下,
scanf
才有意义。花在学习scanf的缺点上的时间并没有花得很好,它也没有真正教会你很多关于C的知识。对于这样的事情,只需一次读一个字符,当你看到两个连续的换行时就停下来。比如:

#include <stdio.h>

int
main(void)
{
        char buf[1024];
        int c;

        char *s = buf;

        while( (c = fgetc(stdin)) != EOF && s < buf + sizeof buf - 1 ){
                if( c == '\n' && s > buf && s[-1] == '\n' ){
                        ungetc(c, stdin);
                        break;
                }
                *s++ = c;
        }
        *s = '\0';
        printf("string entered: %s", buf);
        return 0;
}
#包括
int
主(空)
{
char-buf[1024];
INTC;
char*s=buf;
而((c=fgetc(stdin))!=EOF&sbuf&&s[-1]='\n'){
ungetc(c、stdin);
打破
}
*s++=c;
}
*s='\0';
printf(“输入的字符串:%s”,buf);
返回0;
}

如果你想学习C语言,你应该避免
scanf
。只有在C语言错误的情况下,
scanf
才有意义。花在学习scanf的缺点上的时间并没有花得很好,它也没有真正教会你很多关于C的知识。对于这样的事情,只需一次读一个字符,当你看到两个连续的换行时就停下来。比如:

#include <stdio.h>

int
main(void)
{
        char buf[1024];
        int c;

        char *s = buf;

        while( (c = fgetc(stdin)) != EOF && s < buf + sizeof buf - 1 ){
                if( c == '\n' && s > buf && s[-1] == '\n' ){
                        ungetc(c, stdin);
                        break;
                }
                *s++ = c;
        }
        *s = '\0';
        printf("string entered: %s", buf);
        return 0;
}
#包括
int
主(空)
{
char-buf[1024];
INTC;
char*s=buf;
而((c=fgetc(stdin))!=EOF&sbuf&&s[-1]='\n'){
ungetc(c、stdin);
打破
}
*s++=c;
}
*s='\0';
printf(“输入的字符串:%s”,buf);
返回0;
}
从标准输入读取多行字符串。我怎样才能一直读到只包含EOL的一行

当阅读行的开头时,请记录。如果在开头读取了
'\n'
,请停止

getchar()
方法:

bool beginning = true;
int ch;
while ((ch = getchar()) != EOF) {
  if (beginning) {
    if (ch == '\n') break;
  }
  // Do what ever you want with `ch` 
  beginning = ch == '\n';  
}

fgets()
方法-需要更多代码来处理长度超过N的行

#define N 1024
char buf[N+1];
while (fgets(buf, sizeof buf, stdin) && buf[0] != '\n') {
  ; // Do something with buf
}
从标准输入读取多行字符串。我怎样才能一直读到只包含EOL的一行

当阅读行的开头时,请记录。如果在开头读取了
'\n'
,请停止

getchar()
方法:

bool beginning = true;
int ch;
while ((ch = getchar()) != EOF) {
  if (beginning) {
    if (ch == '\n') break;
  }
  // Do what ever you want with `ch` 
  beginning = ch == '\n';  
}

fgets()
方法-需要更多代码来处理长度超过N的行

#define N 1024
char buf[N+1];
while (fgets(buf, sizeof buf, stdin) && buf[0] != '\n') {
  ; // Do something with buf
}

如果您需要一次读取一个字符,则可以使用
getchar
fgetc
来读取,具体取决于您是从
stdin
还是其他流读取

但是你说你在读字符串,所以我认为
fgets
更合适

主要有两个考虑因素:

  • 最大线路长度
  • 是否处理窗与非窗线条端点
  • 即使你是一个初学者——我不想在这里讨论第二章——你也应该知道你可以抵御它。我至少会说,如果您在一个平台上编译,并从另一个平台的重定向文件中读取stdin,那么您可能必须编写防御

    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    
    int main (int argc, char *argv[]) {
        char buf[32];  // relatively small buf makes testing easier
        int lineContinuation = 0;
        // If no characters are read, then fgets returns NULL.
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
           int l = strlen(buf); // No newline in buf if line len + newline exceeds sizeof(buf)
           if (buf[l-1] == '\n') {
              if (l == 1 && !lineContinuation) {
                 break; // errno should indicate no error.
              }
              printf("send line ending (len=%d) to the parser\n", l);
              lineContinuation = 0;
           } else {
              lineContinuation = 1;
              printf("send line part (len=%d) to the parser\n", l);
           }
        }
        printf("check errno (%d) if you must handle unexpected end of input use cases\n", errno);
    }
    
    #包括
    #包括
    #包括
    int main(int argc,char*argv[]){
    char buf[32];//相对较小的buf使测试更容易
    int lineContinuation=0;
    //如果未读取任何字符,则fgets返回NULL。
    while(fgets(buf,sizeof(buf),stdin)!=NULL){
    int l=strlen(buf);//如果行len+newline超过sizeof(buf),则在buf中没有换行符
    如果(buf[l-1]='\n'){
    如果(l==1&&!行继续){
    break;//errno应该表示没有错误。
    }
    printf(“将行结尾(len=%d)发送到解析器\n”,l);
    lineContinuation=0;
    }否则{
    直线延拓=1;
    printf(“将行部分(len=%d)发送到解析器\n”,l);
    }
    }
    printf(“如果必须处理意外的输入结束用例,请检查errno(%d)”,errno);
    }
    
    如果您需要一次读取一个字符,则可以使用
    getchar
    fgetc
    ,具体取决于您是从
    stdin
    还是其他流读取

    但是你说你在读字符串,所以我认为
    fgets
    更合适

    主要有两个考虑因素:

  • 最大线路长度
  • 是否处理窗与非窗线条端点
  • 即使你是一个初学者——我不想在这里讨论第二章——你也应该知道你可以抵御它。我至少会说,如果您在一个平台上编译,并从另一个平台的重定向文件中读取stdin,那么您可能必须编写防御

    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    
    int main (int argc, char *argv[]) {
        char buf[32];  // relatively small buf makes testing easier
        int lineContinuation = 0;
        // If no characters are read, then fgets returns NULL.
        while (fgets(buf, sizeof(buf), stdin) != NULL) {
           int l = strlen(buf); // No newline in buf if line len + newline exceeds sizeof(buf)
           if (buf[l-1] == '\n') {
              if (l == 1 && !lineContinuation) {
                 break; // errno should indicate no error.
              }
              printf("send line ending (len=%d) to the parser\n", l);
              lineContinuation = 0;
           } else {
              lineContinuation = 1;
              printf("send line part (len=%d) to the parser\n", l);
           }
        }
        printf("check errno (%d) if you must handle unexpected end of input use cases\n", errno);
    }
    
    #包括
    #包括
    #包括
    int main(int argc,char*argv[]){
    char buf[32];//相对较小的buf使测试更容易
    int lineContinuation=0;
    //如果未读取任何字符,则fgets返回NULL。
    while(fgets(buf,sizeof(buf),stdin)!=NULL){
    int l=strlen(buf);//如果行len+newline超过sizeof(buf),则在buf中没有换行符
    如果(buf[l-1]='\n'){
    如果(l==1&&!行继续){
    break;//errno应该表示没有错误。
    }
    printf(“将行结尾(len=%d)发送到解析器\n”,l);
    lineContinuation=0;
    }否则{
    直线延拓=1;
    printf(“将行部分(len=%d)发送到解析器\n”,l);
    }
    }
    printf(“如果必须,请检查错误号(%d))