循环中的C fgets和sscanf:防止无用的循环

时间:2014-09-25 09:17:11

标签: c fgets scanf

我遇到循环问题,fgetssscanf来获取输入。

我知道问题是来自带有输入的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

1 个答案:

答案 0 :(得分: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);

替换整个if()
相关问题