尝试一次后如何停止循环?

时间:2020-05-14 17:41:12

标签: c function loops

我在这里遇到了一些问题。每当我运行此代码时,它都会询问我姓名和出生日期。当我给它时,它会再次询问我,直到我按Ctrl + D。我希望此过程在一段时间后停止,而是询问我,是否要继续?如果我同意,则重复该循环,然后再问我一次。这该怎么做?我尝试过但失败了。

int main(void){
    const char *listing[] = {"Name", "Date of birth"};
    char data[2][51];
    int done = 0;
    FILE *fp;

    fp = fopen("/home/bilal/Documents/file.txt", "w+");
    while (!done){
        for (int i = 0; i < 2; i++){
            printf("Enter your %s: ", listing[i]);
            if (scanf(" %50[^\n]", data[i]) != 1){
                done = 1;
                break;
            }
        }
        if (!done){
            fprintf(fp, "%s %s\n", data[0], data[1]);
        }
    }
    fclose(fp);
    return 0;
}

3 个答案:

答案 0 :(得分:1)

scanf()返回成功匹配和格式化的参数计数,如果输入无效,则返回EOF(-1)。

因此,表达式

char data[1][50]={0};
int val=0;

int count = scanf(" %50[^\n]", data[0]); // 1 parameter to scan and format

对于单个格式化的项目,将返回1。

要获取1以上的内容,您必须扫描并成功格式化多个项目:

count = scanf(" %50[^\n] %d", data[0], &val); //2 parameters to scan and format.

(如果成功,则返回值为2。)

因此,如果您更改循环退出条件以符合这些期望,则循环将正确退出。

if (scanf(" %50[^\n]", data[i]) == 1){//now 'done' will be set to true (1)
                                ^^  

编辑 :说明了上述概念:
(请注意,取消注释文件功能,此插图不需要它们。)

程序循环执行,直到将“姓名”和“出生日期”都捕获到2D字符数组中为止。循环退出条件使用成功的单参数scanf调用计数:

int main(void){
    const char *listing[] = {"Name", "Date of birth"};
    char data[2][51];
    int done = 0;
    int count = 0;//added to allow visibility of return value of scanf function.
    FILE *fp;

    //fp = fopen("/home/bilal/Documents/file.txt", "w+");
    while (done != 2){
        for (int i = 0; i < 2; i++){
            printf("Enter your %s: ", listing[i]);
            count = scanf(" %50[^\n]", data[i]);
            if (count != EOF){
                done += count;
                // 'break' is not needed here, let the loop leave naturally
            }
        }
    }
    if (done == 2)//moved outside of loop because both variables
    {             //need to be populated before printing
        ;//fprintf(fp, "%s %s\n", data[0], data[1]);
    }

    //fclose(fp);
    return 0;
}

答案 1 :(得分:1)

如果我正确解释了您的帖子,请在 first 提示输入姓名和[然后] DOB之后,您要插入“我可以继续吗?”问题。

这是重构的代码:

#include <stdio.h>

int
domore(void)
{
    char buf[51];
    int moreflg = -1;

    while (moreflg < 0) {
        printf("Shall I continue (y/n)? ");
        if (scanf(" %50[^\n]", buf) != 1)
            break;

        switch (buf[0]) {
        case 'y':
        case 'Y':
            moreflg = 1;
            break;

        case 'n':
        case 'N':
            moreflg = 0;
            break;
        }
    }

    if (moreflg < 0)
        moreflg = 0;

    return moreflg;
}

int
main(void)
{
    const char *listing[] = { "Name", "Date of birth" };
    char data[2][51];
    int done = 0;
    int again = 0;
    FILE *fp;

#if 0
    fp = fopen("/home/bilal/Documents/file.txt", "w+");
#else
    fp = fopen("/tmp/file.txt", "w+");
#endif

    while (!done) {
        if (again) {
            if (! domore())
                break;
        }
        again = 1;

        for (int i = 0; i < 2; i++) {
            printf("Enter your %s: ", listing[i]);
            if (scanf(" %50[^\n]", data[i]) != 1) {
                done = 1;
                break;
            }
        }
        if (!done) {
            fprintf(fp, "%s %s\n", data[0], data[1]);
        }
    }

    fclose(fp);

    return 0;
}

答案 2 :(得分:0)

scanf函数返回成功匹配和分配的输入项目数。因此,当您从键盘上键入内容时,在这种情况下,此函数的返回值始终为1(尝试输入字符串,然后将键盘上的每个字符都添加到您的字符串中)。

您可以使用fgets然后与要退出循环的仅包含输入字符“ \ n”的字符串进行比较。

            printf("Enter your %s: ", listing[i]);
            if (strcmp(fgets(data[i], 51, stdin), "\n") == 0){
                done = 1;
                break;
            }

使用此代码,如果您想退出while循环,只需要按ENTER键即可。