我正在尝试使用程序集和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()
具有相同的地址?
谢谢你的帮助
答案 0 :(得分:1)
您的第一个问题是您没有分配任何内存来读取您的输入。 char* line;
将行声明为指向随机位内存的char的指针。因此,通过line[index++] = c
取消引用行会直接导致未定义的行为 - 您正在写入您不拥有的内存。接下来对getline的调用正在击中相同的内存并覆盖之前的内容,这是非常纯粹的侥幸。
所以你需要改变getline来实际读入你拥有的内存。
一种选择是将行声明更改为静态char数组;像static char line[100];
这样的东西。这将为您提供一些实际的内存。但是,这可以保证每次调用getline都会写入相同的内存区域。如果需要在下一次调用getline之后保留输入,那么调用者可以将输入复制到其他地方。
另一个选择是更改getline以接受来自调用者的缓冲区,例如getline(unsigned char password_mode, char *line, size_t line_size)
。这样你就可以为每次调用传递不同的数组。
无论您选择哪种方式,您都希望通过阅读比您有空间更多的字符来确保您没有超出getline内缓冲区的危险。