Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 循环执行不正确_C_Do While - Fatal编程技术网

C 循环执行不正确

C 循环执行不正确,c,do-while,C,Do While,我有一个函数readin()读取许多人的姓名及其对应的电话号码 编号并返回已输入的名称数。字符“#”用于表示用户输入结束 int readin(Employee *emp) { int i=0,j; do { // loop statements to be executed no matter what printf("Enter name:\n"); scanf("%s",emp->name); // stores name inside

我有一个函数readin()读取许多人的姓名及其对应的电话号码 编号并返回已输入的名称数。字符“#”用于表示用户输入结束

int readin(Employee *emp)
{
    int i=0,j;
    do { // loop statements to be executed no matter what
        printf("Enter name:\n");
        scanf("%s",emp->name); // stores name inside structure array
        j = (strcmp(emp->name,"#") != 0); // returns 1 if name not equals to #

    } while(j);{ // while name is not equals to # , execute code below and loop back 'do'
            printf("Enter tel:\n");
            scanf("%s",emp->telno);

            emp++;
            i++;
    }
    return i;
}
预期结果应为:

Enter name:
John
Enter tel:
12345678
Enter name:
#
取得的结果:

Enter name:
John
Enter name:
#
Enter tel:
当j=1时,while循环不会运行,但它会循环回do部分,而不是完全退出循环。
当j=0时,while循环中的代码出于某种原因被执行。请给出建议。

你知道这就是你工作时的样子

do{
 state1;
}
while(statement);

rest of code;
如果这句话是真的, 它将转到状态部分并再次执行,当语句出错时,它将转到代码的其余部分

在你的情况下,当字符串!='#'您将始终进入do while()循环,当语句错误或
j==0
时,您将退出do while循环

我建议:

int readin(Employee* emp)
{
    int i = 0, j =0;
    while (1)
    {
        printf("Enter name:\n");
        scanf("%s", &emp->name);
        if((strcmp(emp->name, "#") == 0))
                    break;

        printf("Enter tel:\n");
        scanf("%s", &emp->telno);

        emp++;
        i++;
    }

    return i;
}

使用
scanf
进行面向行的输入是错误的选择。建议使用
fgets()
或POSIX
getline()
读取用户输入行

为什么使用fgets()?

简而言之,它更健壮,它处理内部空白,允许您输入
“first-last”
名称或
“(409)555-1212”
,就像telno(
scanf()
“%s”
不能)一样,您唯一的责任是验证返回,然后从输入中修剪尾部的
'\n'
。验证返回以处理手动生成的
EOF
,用户在Linux上按Ctrl+d或在windows上按Ctrl+z取消输入。(正如您必须为
scanf()
)做的一样,作为一项好处,您不需要输入
'
来结束输入,因为
fgets()
读取
'\n'
,当单独按下enter键时,用户只需在一个空
名称
行上按enter键即可退出

例如,您可以读取并验证输入的姓名和电话号码字符串是否简单,如下所示:

#define MAXTEL  32      /* if you need a constant, #define one (or more) */
#define MAXNM   64
#define MAXEMP 128

typedef struct {
    char name[MAXNM],
        telno[MAXTEL];
} employee;

int readin (employee *emp)
{
    int n;

    for (n = 0; n < MAXEMP; n++) {  /* loop continually - protect array bounds */
        fputs ("\nEnter name: ", stdout);   /* prompt */
        /* read/validate, check for Enter alone to exit */
        if (!fgets (emp[n].name, MAXNM, stdin) || *emp[n].name == '\n')
            break;
        emp[n].name[strcspn(emp[n].name, "\n")] = 0;    /* trim trailing \n */

        fputs ("Enter tel : ", stdout);                 /* prompt */
        if (!fgets (emp[n].telno, MAXTEL, stdin))       /* read/validate */
            break;
        emp[n].telno[strcspn(emp[n].telno, "\n")] = 0;  /* trim trailing \n */
    }

    return n;
}
您仍然需要输入一个
“#”
来终止输入,这应该是不必要的

你愿意用哪一种

示例

使用以下任一函数:

int main (void) {

    employee e[MAXEMP] = {{ .name = "" }};
    int n = readin (e);

    for (int i = 0; i < n; i++)
        printf ("\nemployee:\n  name  : %s\n  telno : %s\n", 
                e[i].name, e[i].telno);
}
示例使用/输出-scanf()

下面显示了完整的示例,只需将
-dusescan
添加到编译字符串中(或VS的
/D USESCANF
)即可使用
scanf()
版本,默认情况下使用
fgets()
。总的来说,没有理由使用
scanf()
读取两个用户输入字符串。使用面向行的输入函数从用户处读取输入行,您会得到更好的服务:

#include <stdio.h>
#include <string.h>

#define MAXTEL  32      /* if you need a constant, #define one (or more) */
#define MAXNM   64
#define MAXEMP 128

typedef struct {
    char name[MAXNM],
        telno[MAXTEL];
} employee;

#ifndef USESCANF
int readin (employee *emp)
{
    int n;

    for (n = 0; n < MAXEMP; n++) {  /* loop continually - protect array bounds */
        fputs ("\nEnter name: ", stdout);   /* prompt */
        /* read/validate, check for Enter alone to exit */
        if (!fgets (emp[n].name, MAXNM, stdin) || *emp[n].name == '\n')
            break;
        emp[n].name[strcspn(emp[n].name, "\n")] = 0;    /* trim trailing \n */

        fputs ("Enter tel : ", stdout);                 /* prompt */
        if (!fgets (emp[n].telno, MAXTEL, stdin))       /* read/validate */
            break;
        emp[n].telno[strcspn(emp[n].telno, "\n")] = 0;  /* trim trailing \n */
    }

    return n;
}
#else
int readin (employee *emp)
{
    int n;

    for (n = 0; n < MAXEMP; n++) {  /* loop continually - protect array bounds */
        int rtn;            /* variable to save the return of scanf */

        fputs ("\nEnter name: ", stdout);       /* prompt */
        rtn = scanf(" %63[^\n]", emp->name);    /* read into tmp saving return */

        if (rtn == EOF) {   /* handle EOF - user presses Ctrl+d (Ctrl+z win) */
            fputs ("(user canceled input)\n", stderr);
            break;
        }
        else if (rtn == 1 && *emp->name == '#') /* good input and '#' -- bail */
            break;

        for (;;) {  /* loop contianually until valid telno entered */

            fputs ("Enter tel : ", stdout);         /* prompt */
            rtn = scanf(" %31[^\n]", emp->telno);   /* read saving return */

            if (rtn == EOF) {       /* handle EOF - ditto */
                fputs ("(user canceled input)\n", stderr);
                break;
            }
            else if (rtn == 1) {    /* good input */
                /* further validate telno here */
                break;
            }
        }   /* empty trailing \n from stdin */
        for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}

        emp++;  /* advance pointer */
    }

    return n;   /* return success */
}
#endif

int main (void) {

    employee e[MAXEMP] = {{ .name = "" }};
    int n = readin (e);

    for (int i = 0; i < n; i++)
        printf ("\nemployee:\n  name  : %s\n  telno : %s\n", 
                e[i].name, e[i].telno);
}
#包括
#包括
#定义MAXTEL 32/*如果需要常数,请定义一个(或多个)*/
#定义maxm64
#定义MAXEMP 128
类型定义结构{
字符名[MAXNM],
telno[MAXTEL];
}员工;
#ifndef USESCANF
int readin(员工*emp)
{
int n;
对于(n=0;nname);/*读入tmp保存返回*/
如果(rtn==EOF){/*句柄EOF-用户按下Ctrl+d(Ctrl+z)*/
fputs(“(用户取消输入)\n”,stderr);
打破
}
如果(rtn==1&&*emp->name=='#')/*输入正确且'#'--bail*/
打破
for(;;){/*循环,直到输入有效的telno*/
fputs(“输入电话:,标准输出);/*提示*/
rtn=scanf(“%31[^\n]”,emp->telno);/*读取保存返回*/
if(rtn==EOF){/*句柄EOF-同上*/
fputs(“(用户取消输入)\n”,stderr);
打破
}
else如果(rtn==1){/*输入正确*/
/*在这里进一步验证telno*/
打破
}
}/*空尾随\n来自标准输入*/
对于(int c=getchar();c!='\n'&&c!=EOF;c=getchar()){}
emp++;/*高级指针*/
}
返回n;/*返回成功*/
}
#恩迪夫
内部主(空){
雇员e[MAXEMP]={{.name=”“};
int n=读入(e);
对于(int i=0;i

仔细检查一下,如果您还有其他问题,请告诉我。

}while(j)上的缩进或行分割(或不存在缩进或行分割);{
令人担忧。
do{…}while(j)
循环以分号结尾。
{
是一个独立的复合语句,与
do
-
while
循环无关。
do
-
while
将重复输入员工姓名,直到您用
覆盖它(循环将结束,但之前的条目已丢失-名称为
“#”
)。然后输入电话号码once@JonathanLeffler理解。似乎我对do循环有一个误解。我错过了
emp++
,它将数组作为参数传递。因此,您可以得到多个em
$ ./bin/empnametelnoarray

Enter name: John Q. Public
Enter tel : 444-1212

Enter name: Sally P. Public
Enter tel : 444-1222

Enter name: Mary Jane
Enter tel : 444-1223

Enter name:

employee:
  name  : John Q. Public
  telno : 444-1212

employee:
  name  : Sally P. Public
  telno : 444-1222

employee:
  name  : Mary Jane
  telno : 444-1223
$ ./bin/empnametelnoarray

Enter name: John Q. Public
Enter tel : 444-1212

Enter name: Sally P. Public
Enter tel : 444-1222

Enter name: Mary Jane
Enter tel : 444-1223

Enter name: #

employee:
  name  : John Q. Public
  telno : 444-1212

employee:
  name  : Sally P. Public
  telno : 444-1222

employee:
  name  : Mary Jane
  telno : 444-1223
#include <stdio.h>
#include <string.h>

#define MAXTEL  32      /* if you need a constant, #define one (or more) */
#define MAXNM   64
#define MAXEMP 128

typedef struct {
    char name[MAXNM],
        telno[MAXTEL];
} employee;

#ifndef USESCANF
int readin (employee *emp)
{
    int n;

    for (n = 0; n < MAXEMP; n++) {  /* loop continually - protect array bounds */
        fputs ("\nEnter name: ", stdout);   /* prompt */
        /* read/validate, check for Enter alone to exit */
        if (!fgets (emp[n].name, MAXNM, stdin) || *emp[n].name == '\n')
            break;
        emp[n].name[strcspn(emp[n].name, "\n")] = 0;    /* trim trailing \n */

        fputs ("Enter tel : ", stdout);                 /* prompt */
        if (!fgets (emp[n].telno, MAXTEL, stdin))       /* read/validate */
            break;
        emp[n].telno[strcspn(emp[n].telno, "\n")] = 0;  /* trim trailing \n */
    }

    return n;
}
#else
int readin (employee *emp)
{
    int n;

    for (n = 0; n < MAXEMP; n++) {  /* loop continually - protect array bounds */
        int rtn;            /* variable to save the return of scanf */

        fputs ("\nEnter name: ", stdout);       /* prompt */
        rtn = scanf(" %63[^\n]", emp->name);    /* read into tmp saving return */

        if (rtn == EOF) {   /* handle EOF - user presses Ctrl+d (Ctrl+z win) */
            fputs ("(user canceled input)\n", stderr);
            break;
        }
        else if (rtn == 1 && *emp->name == '#') /* good input and '#' -- bail */
            break;

        for (;;) {  /* loop contianually until valid telno entered */

            fputs ("Enter tel : ", stdout);         /* prompt */
            rtn = scanf(" %31[^\n]", emp->telno);   /* read saving return */

            if (rtn == EOF) {       /* handle EOF - ditto */
                fputs ("(user canceled input)\n", stderr);
                break;
            }
            else if (rtn == 1) {    /* good input */
                /* further validate telno here */
                break;
            }
        }   /* empty trailing \n from stdin */
        for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}

        emp++;  /* advance pointer */
    }

    return n;   /* return success */
}
#endif

int main (void) {

    employee e[MAXEMP] = {{ .name = "" }};
    int n = readin (e);

    for (int i = 0; i < n; i++)
        printf ("\nemployee:\n  name  : %s\n  telno : %s\n", 
                e[i].name, e[i].telno);
}