程序循环在id号码调用以及不将信息输入到数组

时间:2016-09-17 04:05:23

标签: c arrays printf

所以我的程序试图从用户那里获取一些信息并将它们添加到一个结构数组中。如果你能帮助我会很感激。该程序将继续循环播放"请输入有效的ID号:"而且我不知道为什么。此外,当稍后在main中使用打印功能时,不会将用户的信息添加到阵列中。

void add_employee(Employee *db, int db_size){
    int tst1, tst2, tst3, tst4 = 0;
    char temp_first[MAXNAME];
    char temp_last[MAXNAME];
    int temp_six_digit_id;
    int temp_salary;
    db_size++;
    printf("Please enter a first name:\n");
    if(scanf("%s", temp_first) == 1){tst1 == 1;}
    else{
            printf("Please enter a valid name.\n");
            while(tst1 == 0){
                    if(scanf("%s", temp_first) == 1){tst1 == 1;}
                    else{printf("Please enter a valid name.\n");}
                    }
    }
    printf("Please enter a last name:\n");
    if(scanf("%s", temp_last) == 1){tst2 == 1;}
    else{
            printf("Please enter a valid name.\n");
            while(tst2 == 0){
                    if(scanf("%s", temp_last) == 1){tst2 == 1;}
                    else{printf("Please enter a valid name.\n");}
                    }
    }
    printf("Please enter the six digit ID number:\n");
    if(scanf("%d", &temp_six_digit_id) == 1){tst3 ==1;}
    else{
            printf("Please enter a valid ID number:\n");
            while(tst3 == 0){
                    if(scanf("%d", &temp_six_digit_id) == 1){tst3 == 1;}
                    else{printf("Please enter a valid ID number:\n");}
                    }
    }
    printf("Please enter the salary:\n");
    if(scanf("%d", &temp_salary) ==1){tst4 == 1;}
    else{
            printf("Please enter a valid Salary:\n");
            while(tst3 == 0){
                    if(scanf("%d", &temp_salary) == 1){tst3 == 1;}
                    else{printf("Please enter a valid Salary:\n");}
            }
    }
    strcpy(db[db_size].first_name, temp_first);
    strcpy(db[db_size].last_name, temp_last);
    db[db_size].six_digit_id = temp_six_digit_id;
    db[db_size].salary = temp_salary;

}

4 个答案:

答案 0 :(得分:0)

tst3==1更改为tst3=1tst1tst2也是如此。

赋值运算符(=)和相等运算符(==)似乎相似,但出于完全不同的原因使用。

赋值运算符(=)用于为lvalue赋值。

而等式运算符(==)用于比较两个值或表达式。如果相等为真,则结果为1;如果相等为假,则结果为0

答案 1 :(得分:0)

您需要使用赋值运算符。

if(scanf("%s", temp_first) == 1){tst1 == 1;}
//change tst1 == 1; to tst1 = 1;

if(scanf("%s", temp_last) == 1){tst2 == 1;}
//change tst2 == 1; to tst2 = 1;

if(scanf("%d", &temp_six_digit_id) == 1){tst3 == 1;}
//change tst3 == 1; to tst3 = 1;

在最后的情况下,您必须使用变量tst4但是您正在使用tst3

if(scanf("%d", &temp_salary) ==1){tst4 == 1;}  // use tst4 = 1
else{
        printf("Please enter a valid Salary:\n");
        while(tst3 == 0){  // you need to use tst4 == 0

        if(scanf("%d", &temp_salary) == 1){tst3 == 1;}  //use tst4 = 1;
        else{printf("Please enter a valid Salary:\n");}
}

答案 2 :(得分:0)

要比较值,您需要使用==并指定值=

答案 3 :(得分:0)

继续发表评论时,使用scanf阅读用户输入时需要考虑许多因素。这就是为什么,作为一般命题,面向行的是首选(例如fgetsgetline),这将消除因留下'\n'而导致的问题。 输入缓冲区(此处为stdin)。 fgetsgetline都会读取并包含换行符(当用户在键盘上按 Enter 时生成。在使用其中任何一个读取后,只需将读取的字符串传递给sscanf,即可从读取的字符串中解析所需的信息。

也就是说,您可以使用scanf来处理输入,但您的负责处理'\n'

在查看scanf之前,让我们谈谈您目前拥有的void类型的功能。这完全是对回报的浪费,可用于指示输入的成功或失败。你将如何处理用户取消输入(比如 Ctrl + d (在Linux上)或 Ctrl + z (windoze))当在函数中输入时,总是提供一个返回值,可用于指示成功/失败。在这里,您可以简单地返回指向新节点的指针以指示成功,或者NULL指示失败。然后,您的函数将是Employee *类型,而不是void

也就是说,带有scanf格式说明符的%s读取,但不包括第一个空格或 '\n'。因此,当您的用户输入name并按Enter键时,您会在变量中捕获"name",但'\n'仍在stdin中。如果您下一次输入是数字类型,或者键入char,则scanf会愉快地使用'\n'作为用户的值(假设scanf跳过了提示)。为了防止scanf'\n'作为下一个值,无论其类型如何,您都可以在格式说明符之前加上space(例如" %s" }}这将导致scanf在第一个非空白字符('\n'被视为空格)之前忽略所有空格。

您还可以将分配抑制运算符用于scanf。 (例如"%s%*c"'*'之前的c告诉scanf 读取并丢弃下一个字符(不影响匹配)由scanf返回的计数。您可以在man scanf中阅读相关内容。 (在读取可包含嵌入空格的最大字符数时也更有意义,例如" %99[^\n]%*c"用于最大100 char字符串 - 包括nul-byte

要阅读不包含scanf空格的字符串,您可以确保您收到输入,同时还允许用户使用手册EOF取消输入而不包含所有tst1, tst2, ...个变量。以temp_first值为例。你可以这样做:

    int return_val;  /* capture the return of scanf */
    ...
    printf ("\nPlease enter a first name: ");
    while ((return_val = scanf (" %s", temp_first)) != 1) {
        if (return_val == EOF)      /* trap manual EOF  */
            return NULL;            /* return NULL for error */
        fprintf (stderr, "error: invalid first name.\n");
        printf ("Please enter a first name: ");
    }

这将以更加直接的方式完成您对所有其他tst值的尝试。

当你去阅读temp_six_digit_id时,将输入作为字符串更有意义。这样可以确定您确实6个数字是对strlen的简单调用。在这里你可以做类似的事情:

    printf ("Please enter the six digit ID number: ");
    while ((return_val = scanf (" %s", temp_id)) != 1 ||
            strlen (temp_id) != 6) {
        if (return_val == EOF)
            return NULL;
        fprintf (stderr, "error: invalid ID.\n");
        printf ("Please enter the six digit ID number: ");
    }
    temp_six_digit_id = (int)strtol (temp_id, NULL, 10);
    /* strtol validations omitted (see man strtod example) */

(您也可以将salary作为字符串阅读并保留错误检查/处理strtol提供的内容。

下面是一个简短的示例,它将所有部分组合在一起,您可以在完整代码之外进行实验。你必须使它适应你的其余代码,但这应该是相对微不足道的。

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

/* constants, max(employees, ID, salary, name) */
enum { MAXE = 3, MAXID = 32, MAXSAL = 64, MAXNAME = 256 };

typedef struct {
    char first_name[MAXNAME],
        last_name[MAXNAME];
    int six_digit_id,
        salary;
} Employee;

int main (void) {

    Employee db[MAXE] = {{ .first_name = "" }};
    char temp_first[MAXNAME] = "",
         temp_last[MAXNAME] = "",
         temp_id[MAXID] = "",
         temp_sal[MAXSAL] = "";
    int temp_six_digit_id = 0,
        temp_salary = 0,
        return_val = 0,
        db_size = 0;

    while (db_size < MAXE) {

        printf ("\nPlease enter a first name: ");
        while ((return_val = scanf (" %s", temp_first)) != 1) {
            if (return_val == EOF)      /* trap manual EOF  */
                return 1;           /* return NULL for error */
            fprintf (stderr, "error: invalid first name.\n");
            printf ("Please enter a first name: ");
        }

        printf ("Please enter a last name: ");
        while ((return_val = scanf (" %s", temp_last)) != 1) {
            if (return_val == EOF)
                return 1;
            fprintf (stderr, "error: invalid last name.\n");
            printf ("Please enter a last name: ");
        }

        printf ("Please enter the six digit ID number: ");
        while ((return_val = scanf (" %s", temp_id)) != 1 ||
                strlen (temp_id) != 6) {
            if (return_val == EOF)
                return 1;
            fprintf (stderr, "error: invalid ID.\n");
            printf ("Please enter the six digit ID number: ");
        }
        temp_six_digit_id = (int)strtol (temp_id, NULL, 10);
        /* strtol validations omitted (see man strtod example) */

        printf ("Please enter the salary: ");
        while ((return_val = scanf (" %s", temp_sal)) != 1) {
            if (return_val == EOF)
                return 1;
            fprintf (stderr, "error: invalid salary.\n");
            printf ("Please enter a the salary: ");
        }
        temp_salary = (int)strtol (temp_sal, NULL, 10);

        strcpy(db[db_size].first_name, temp_first);
        strcpy(db[db_size].last_name, temp_last);
        db[db_size].six_digit_id = temp_six_digit_id;
        db[db_size].salary = temp_salary;

        db_size++;  /* 'db_size' is a copy here, changes are not visible in the
                     caller, pass a pointer to db_size to make change visible */
    }

    for (int i = 0; i < db_size; i++)
        printf ("\n name   : %s %s\n ID     : %d\n salary : %d\n",
                db[i].first_name, db[i].last_name, db[i].six_digit_id,
                db[i].salary);

    return 0;
}

(请特别注意有关db_size的评论。如果您希望在调用函数中看到db_size的更改可见,则需要将指针传递给db_size而不是db_size本身。)

使用/输入示例

$ ./bin/emp_input

Please enter a first name: Mary
Please enter a last name: Jane
Please enter the six digit ID number: 123
error: invalid ID.
Please enter the six digit ID number: 123456
Please enter the salary: 937

Please enter a first name: John
Please enter a last name: Doe
Please enter the six digit ID number: 234567
Please enter the salary: 1024

Please enter a first name: Bill
Please enter a last name: Jones
Please enter the six digit ID number: 234568
Please enter the salary: 1020

 name   : Mary Jane
 ID     : 123456
 salary : 937

 name   : John Doe
 ID     : 234567
 salary : 1024

 name   : Bill Jones
 ID     : 234568
 salary : 1020

注意:有很多方法可以处理用户输入。选择这与实际的原始尝试接近。如果您有任何问题或进一步实施的问题,请告诉我,我们将很乐意为您提供进一步的帮助。