2014-09-25 92 views
0

我有一个循环问题,并且fgetssscanf以获得输入。C fgets和sscanf在循环中:防止无用的循环

我知道的问题是从输入的malloc的大小。如果用户输入的号码大于malloc我想再次要求输入一个新号码。 但是在这段代码中,如果用户输入的数字太大,我认为它会循环很多时间(字/ 8的大小)。

如何再次询问用户输入新号码,例如4次循环。 看到我用大号制作的例子。

这个想法是在循环后释放输入,但它不起作用。有任何想法吗 ?

有我的代码:

#include <stdio.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <getopt.h> 
#include <stdbool.h> 
#include <string.h> 


int main(void) { 
    char x[8]; 
    char y[8]; 
    int result = 0; 
    char *input=malloc(sizeof(char)*8); 
    bool answer = 0; 
    char *pos; 

    while(!answer) { 

     fgets(input, sizeof(input)-1, stdin); 
     //remove the /n from fgets 
     if ((pos=strchr(input, '\n')) != NULL) 
      *pos = '\0'; 

     result = sscanf (input, "%s %s", x, y); 
     printf("%d\n", result); 
     if(result < 2) { 
      fprintf(stderr, "There is an error with the number you give, try again\n"); 
     } else { 
      printf("%s\n", x); 
      printf("%s\n", y); 
     } 

    } 
    return 0; 
} 

和输出为: “01 01”

01 01 
2 
01 
01 

输出为:000000005 000000005

0000000000005 000000000000005 
1 
There is an error with the number you give, try again 
1 
There is an error with the number you give, try again 
2 
5 
0000 
1 
There is an error with the number you give, try again 
1 
There is an error with the number you give, try again 
+3

'的sizeof(输入)整体更换,如果()'是指针的大小,而不是malloc的内存。你很幸运,这两个数字都是8的好机会。 – mch 2014-09-25 09:22:53

+1

假设你修改了你的输入缓冲区来动态增加消耗你的行内容,你会发现一个全新的问题,试图像''sscanf''这样的字符串。 0000000000005“'变成'char [8]',对吗?我的意思是,你试图把14个字符放到一个只能容纳8个字符的缓冲区中,当你使用它时,'sscanf'是幸福地不知道这个限制的。 – WhozCraig 2014-09-25 09:32:37

回答

1

与fgets()不当它比缓冲区长时,丢弃其余的行。你必须自己做。

如果你看看这个代码,我经常与fgets使用,你会看到两个任务分离,以及在什么情况哪一个做:

/*Returns 0 if OK, a negative value if EOF.*/ 
int fpurge(FILE *f) 
{ 
    int c; 
    while((c=fgetc(f))!=EOF && c!='\n') 
    { } 
    return (c==EOF ? -1 : 0); 
} 

/* Returns a nonzero value if found, zero if not. */ 
int truncate_newline(char *str) 
{ 
    int bRet=0; 
    if(str!=NULL) 
    { 
     char *pNewLine = strchr(str, '\n'); 
     if(pNewLine!=NULL) 
     { 
      bRet = 1; 
      *pNewLine = '\0'; 
     } 
    } 
    return bRet; 
} 

/* Returns 0 if buffer is full, a positive value if line is complete, 
    a negative value if EOF (implies buffer full). */ 
int fclean(char *str, FILE *f) 
{ 
    int ret = 1; 
    if(!truncate_newline(str)) 
     ret = fpurge(f); 
    return ret; 
} 

你可以看到你自己的代码执行truncate_newline部分,但不是“扔掉剩下的线”(这里是功能fpurge)的一部分。

如果你正是如此改变你的代码,它应该工作:

#include <stdio.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <getopt.h> 
#include <stdbool.h> 
#include <string.h> 

#define BUFFER_SIZE 8 

int main(void) { 
    char x[BUFFER_SIZE]; 
    char y[BUFFER_SIZE]; 
    int result = 0; 
    char *input=calloc(BUFFER_SIZE, sizeof(char)); 
    bool answer = 0; 
    char *pos; 

    while(!answer) { 

     fgets(input, BUFFER_SIZE, stdin); 
     //remove the /n from fgets 
     if ((pos=strchr(input, '\n')) != NULL) 
      *pos = '\0'; 
     else 
     { 
      int c; 
      while((c=getchar())!='\n' && c!=EOF) {} 
     } 

     result = sscanf (input, "%s %s", x, y); 
     printf("%d\n", result); 
     if(result < 2) { 
      fprintf(stderr, "There is an error with the number you give, try again\n"); 
     } else { 
      printf("%s\n", x); 
      printf("%s\n", y); 
     } 

    } 
    return 0; 
} 

或者干脆fclean(input, stdin);

+0

Thx为解释!在你的代码中,替换'char * pNewline = strchr(str,'\ n');''char * pNewLine = strchr(str,'\ n');' – mpgn 2014-09-25 09:29:20

+0

谢谢,纠正。 – Medinoc 2014-09-25 09:33:00

+0

@martialdidit ** PS **:fgets()已在其大小参数中包含空终止符,您无需自行减1。 – Medinoc 2014-09-25 09:35:48