繁体   English   中英

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

[英]C fgets and sscanf in loop : prevent useless looping

我在循环以及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

如果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;
}

或者只是将整个if()替换为fclean(input, stdin);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM