0

我正在尝试使用程序集和 C 开发一个基本的操作系统,但我一直在开发键盘驱动程序。我使用以下两个函数通过键盘从用户那里获取一行

char getchar() {
    char c;
    int i;

    while(char_count == 0);

    c = buffer[0];

    for(i=0 ; i<KEYBOARD_BUFFER_SIZE ; i++) {
    buffer[i] = buffer[i+1];
    }

    char_count--;
    push_index--;

    return c;
}

char* getline(unsigned char password_mode) {
    char* line;
    char c = 0x00;
    int index = 0;

    while(c != '\n') {

        if(c) {
            if(!password_mode)
                printch(c);
            else
                printch('*');

            if(c == '\b')
                index--;
            else
                line[index++] = c;
    }

            c = getchar();
    }

    line[index] = '\0';

    return line;
}

但是,当我尝试从用户那里获取用户名和密码时,我要求他先输入用户名,然后输入密码,问题是密码覆盖了用户名,导致数据不正确。密码如何写在用户名上?这是否意味着每次访问函数时char* arr分配的地址都相同?getline()谢谢你的帮助

4

1 回答 1

1

您的第一个问题是您没有分配任何内存来读取您的输入。char* line;将 line 声明为指向 char 的指针,指向内存的随机位。因此,取消引用 line vialine[index++] = c会将您直接带入未定义的行为 - 您正在写入您不拥有的内存。对 getline 的后续调用会碰到相同的内存并覆盖之前的内容,这几乎是纯粹的侥幸。

因此,您需要更改 getline 以实际读入您拥有的内存。

一种选择是将 line 的声明更改为静态 char 数组;类似的东西static char line[100];。这会给你一些实际的记忆。然而,这保证了每次调用 getline 肯定会写入相同的内存区域。如果在下次调用 getline 之后需要保留输入,则由调用者将其复制到其他地方。

另一种选择是更改 getline 以接受来自调用者的缓冲区,例如getline(unsigned char password_mode, char *line, size_t line_size). 这样,您可以将不同的数组传递给每个调用。

无论您选择哪个选项,您还希望通过读取超出您空间的字符来确保您不会有超出 getline 内缓冲区的危险。

于 2013-05-07T23:39:40.350 回答