2016-01-24 37 views
2

这里是我当前的代码:C如何忽略用户输入中的空行?

int num = 0; 
char c = '#'; 

scanf("%d",&num); 
do{ 
    for (int i=0;i<num;i++){ 
     printf("%c",c); 
    } 
    printf("\n"); 
} 
while (scanf("%d", &num) == 1); 

如何我要这样,如果用户不输入任何内容,该方案将不会吐出一个换行符?

任何帮助表示赞赏,谢谢!

+1

的可能的复制[获取scanf函数退出时,它读取一个换行符?](http://stackoverflow.com/questions/3723044/get-scanf-to-quit-when-it-reads-a-换行) –

+0

嗯,你所说的“空”,我只会调用''\ n“'的输入并保存''”'_empty_输入的想法。 – chux

+1

'scanf'的'%d'将忽略(跳过)前面的换行符(空格)。 – BLUEPIXY

回答

2

此代码应为工作,你想做什么:

#include <stdio.h> 

int main() 
{ 
    int num = 0; 
    char c = '#'; 
    char readLine[50]; 

    while ((fgets(readLine, sizeof readLine, stdin) != NULL) && sscanf(readLine, "%d", &num) == 1) 
    { 
     for (int i=0;i<num;i++){ 
       printf("%c",c); 
     } 
     printf("\n"); 
     fflush(stdout); 
    } 
    return 0; 
} 

这段代码的行为如下:与fgets会读什么你的标准流(标准输入)的输入,并把它放在readLine数组。然后程序将尝试读取readLine变量中的数字,并将其放入具有sscanf函数的num变量中。如果读取了一个数字,程序将执行您在问题中出现的行为(编写一个#字符“num”次),然后返回到循环的开头。如果读取了其他数字,则循环停止。

+0

您不会忽略空白行,您会停止空白行中的程序。删除'&&(readLine [0]!='\ n')'会解决这个问题。无论如何,这是不需要的。 – chqrlie

0

一般而言,请避免scanf。在输入流中留下未处理的垃圾非常容易。相反,阅读整行,然后使用sscanf(或其他)来处理它。这保证你不会遇到部分读取行,这些都很难调试。

我更喜欢getlinefgets来读取线条。 fgets要求您猜测输入可能会有多长时间,并且输入可能会被截断。 getline会分配内存来为你读取行,避免缓冲区溢出或截断问题。

注意:getline is it's not a C standard function, but a POSIX one和相当近的(2008),尽管它在此之前是一个GNU扩展。一些较早的编译器可能没有它。

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    char c = '#'; 
    char *line = NULL; 
    size_t linelen = 0; 

    /* First read the whole line */ 
    while(getline(&line, &linelen, stdin) > 0) { 
     /* Then figure out what's in it */ 
     long num = 0; 
     if(sscanf(line, "%ld", &num) > 0) { 
      for(int i = 0; i < num; i++) { 
       printf("%c", c); 
      } 
      printf("\n"); 
     } 
    } 

    free(line); 

    return 0; 
} 

if(sscanf(line, "%ld", &num) > 0) {将忽略不图案,的任何部分匹配,如空白行或一个完整的单词的线路的任何线路,通过检查多少东西相匹配。但它仍然会处理0作为有效输入。

$ ./test 
foo 
bar 
foo123 
12 
############ 

1 
# 
0 

2 
## 

我也感动num内循环,以保证它的重新初始化每个迭代,并把你的变量在最小范围,以避免干扰的一般原则。我把它升级到long int更能够处理难以预测的大数字用户可能输入的内容。

0

以下是我多年来使用fgets()和sscanf()函数完成输入解析的方法。我不会写很多C++,如果我可以将代码保留在旧式ansi C中,那么我就可以。 stdio.h库中的fgets和sscanf函数是通用的,并且始终可用于任何平台。

对于用于读取任何内容的字符数组,我通常将LINE_SIZE设置为256或512,即使我通常知道要读取的行是80个字符或更少。今天任何计算机拥有超过1GB的RAM,不值得担心分配额外的500字节。很显然,如果你不知道该输入线有多长,那么你要么必须:

猜测什么LINE_SIZE应设置,而不用担心它

或验证换行符存在于线[ ]在调用fgets()之后的空字符之前。

# include <stdio.h> 

# define LINE_SIZE 256 

int main (int argc, char *argv[]) 
{ 
    FILE *fp; 
    char line[LINE_SIZE]; 
    int nn; 
    int value; 

    fp = fopen("somefile", "r"); 

    fgets(line, LINE_SIZE, fp); 

    /* 
     this way to read from standard input (i.e. the keyboard) 
     using fgets with stdin prevents compiler warning when using 
     deprecated gets function 

     fgets(line, LINE_SIZE, stdin); 
    */ 

    if (line[0] != '\n') 
    { 
     /* definitely not a blank line */ 

     nn = sscanf(line, "%d", &num); 

     if (nn == 1) 
     { 
      /* some number placed into num variable that met the 
       %d conversion for the sscanf function 
      */ 
     } 
    } 
    return 0;