2014-09-25 80 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