C输入和返回

nhn9ugyo  于 2023-02-07  发布在  其他
关注(0)|答案(2)|浏览(132)

我正在尝试开发一个员工管理系统,该系统将员工信息作为输入,并相应地打印输出。
结构:

struct employee
{
    char empId[10];
    char name[20];
    char empType[10];
    int dd, mm, yyyy;
};

检查字符串是否只包含整数的程序:

void checkValidId(char *id)
{
    int count = 0, i;

    for(i = 0; i < strlen(id); i++)
    {
        if(id[i] >= '0' && id[i] <= '9')
        {
            count++;
        }
    }
    if(count == strlen(id))
        // continue executing next statements of input() function
    else
        // take the empId input again
}

获取输入的函数:

struct employee input()
{
    struct employee e;

    printf("Enter Employee ID: ");
    scanf("%s", &e.empId); 
    checkValidId(e.empId);

    // next statements ....
}

这里我试着检查输入的字符串empId是否只包含整数,这是由checkValidId()完成的,如果是,那么程序继续执行下一个语句,否则我想再次获取输入的empId,怎么做?
请求支援!
谢谢!

exdqitrt

exdqitrt1#

包括标头<ctype.h>,并使用isdigit测试字符是否在集合'0' ... '9'中。
包括标头<stdbool.h>,并将checkValidId的签名更改为

bool checkValidId(const char *id)

以便向调用函数指示结果。
checkValidId中,循环字符串中的每个字符。如果当前字符不是数字,则立即从函数返回false。如果循环完成,则所有字符必须是数字,然后可以返回true
注意,这里没有理由调用strlen,只需循环直到当前字符为空终止字节。
&e.empId的类型为char (*)[10],即10个字符数组的 * 指针 *。scanf说明符"%s"要求类型为char *pointer-to-char。数组在传递给函数时将 * 衰减 * 为指向其第一个元素的指针,因此此处调用scanf的“正确”方法是scanf("%s", e.empId);
也就是说,您必须检查scanf的返回值是否是 * 预期的转换次数 *,否则您将对不确定的数据进行操作。
此外,未绑定的"%s"as dangerous as the gets function,因为它不知道何时停止阅读数据,并且很容易溢出提供的缓冲区。您必须提供 * 最大字段宽度 * 以防止scanf读取过多字符。这最多应该是缓冲区大小减1,为空终止字节留出空间。
安全使用scanf的示例:

if (1 != scanf("%9s", e.empId)) {
    /* handle input stream error */
}

请注意,当scanf无法执行转换时,有问题的数据会留在流中。使用scanf从错误输入中恢复非常困难,因此通常建议使用基于行的方法来处理用户输入。使用fgets可以实现这一点。
如果缓冲区中有空间,fgets在读取时会包含换行符。参见Removing trailing newline character from fgets() input了解strcspn的示例用法,它也可以用作获取输入长度的方法。
若要重复要求用户输入,请使用无限循环。当用户正确输入请求的数据或发生严重错误时,循环中只有break
下面是一个使用所讨论方法的示例程序:

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

struct employee {
    char empId[10];
    /* ... */
};

bool checkValidId(const char *id)
{
    for (size_t i = 0; id[i] != '\0'; i++)
        if (!isdigit((unsigned char) id[i]))
            return false;

    return true;
}

bool getEmployee(struct employee *e, FILE *stream)
{
    char buffer[256];

    while (1) {
        printf("Enter employee ID: ");

        if (!fgets(buffer, sizeof buffer, stream))
            return false;

        size_t length = strcspn(buffer, "\r\n");
        /* remove the newline */
        buffer[length] = '\0';

        if (!length)
            fprintf(stderr, "Invalid ID. Zero length.\n");
        else if (length >= sizeof e->empId)
            fprintf(stderr, "Invalid ID. Too long.\n");
        else if (!checkValidId(buffer))
            fprintf(stderr, "Invalid ID. Contains non-digit character(s).\n");
        else {
            strcpy(e->empId, buffer);
            break;
        }

        puts("Try again.");
    }

    return true;
}

int main(void)
{
    struct employee emp;

    if (!getEmployee(&emp, stdin))
        return 1;

    printf("ID: <%s>\n", emp.empId);
}

正在与此程序交互:

Enter employee ID: foobar
Invalid ID. Contains non-digit character(s).
Try again.
Enter employee ID: 
Invalid ID. Zero length.
Try again.
Enter employee ID: 1234567890
Invalid ID. Too long.
Try again.
Enter employee ID: 42
ID: <42>
31moq8wy

31moq8wy2#

  1. checkValidId应该返回int,这样它就可以告诉调用者id是否有效。
    1.如果checkValidId的返回值指示错误的id,则调用方(例如input)应循环。
    1.根本不需要使用strlen
    1.不需要比较长度。可以使用更简单的算法。
    1.如果检测到无效字符,我们可以停止循环
    下面是重构后的代码:
struct employee {
    char empId[10];
    char name[20];
    char empType[10];
    int dd, mm, yyyy;
};

// Program to check if the string contains only integers:
// RETURNS: 1=input valid, 0=retry
int
checkValidId(char *id)
{
    int valid = 0;

    for (int i = 0; id[i] != 0; i++) {
        valid = (id[i] >= '0') && (id[i] <= '9');
        if (! valid)
            break;
    }

    return valid;
}

// Function to take input:
struct employee
input(void)
{
    struct employee e;

    while (1) {
        printf("Enter Employee ID: ");
        scanf("%s", &e.empId);
        if (checkValidId(e.empId))
            break;
    }

    // next statements ....
}

相关问题