我编写了以下函数来在输入时动态分配输入字符串,而不会询问用户多长的字符数。
#include<stdio.h>
#include<stdlib.h>
char* dyninp (char str[], int *n) {
char ch;
int i = 0;
do {
ch = getchar();
str = (char *) realloc(str, (i+1)*sizeof(char));
str[i] = ch;
i++;
} while (ch != '\n');
/*substitute '\n' with '\0'*/
str[i-1] = '\0';
if (n != NULL) {
/*i contains the total lenght, including '\0'*/
*n = i-1;
}
/*because realloc changes array's address*/
return str;
}
/*it is called in this way:
char *a;
int n;
a = dyninp (a, &n);
*/
此代码有效,但我对此有一些疑问:
为什么会这样?
我不明白为什么,当我执行它时,我也可以在按Enter键之前删除字符。 getchar()
函数在每次迭代时只读取一个字符,这个字符写入数组,所以我怎么能删除一些呢?
如果getchar()
在收到'\ 127'时删除了前一个字符,那么循环应该像任何其他字符一样继续执行。但这不会发生,因为当循环结束时,“i”总是包含确切数量的元素。
我的代码有效吗?如果不是,我怎么能做得更好(甚至使用内置功能)?
答案 0 :(得分:1)
回答第一个问题:
原因可能是终端驱动程序中的缓冲。注释部分提供了一个简短的解释here。 0x000001bd76170c44: lock cmpxchg %ecx,(%r11)
0x000001bd76170c49: sete %r10b
0x000001bd76170c4d: movzbl %r10b,%r10d ;*invokevirtual compareAndSwapInt
; - WeakVsNonWeak::strong@25 (line 23)
; - WeakVsNonWeak::main@46 (line 14)
0x0000024f56af1097: lock cmpxchg %r11d,(%r8)
0x0000024f56af109c: sete %r10b
0x0000024f56af10a0: movzbl %r10b,%r10d ;*invokevirtual weakCompareAndSwapInt
; - WeakVsNonWeak::strong@25 (line 23)
; - WeakVsNonWeak::main@46 (line 14)
函数在接收到整个字符串并逐字符地返回它之前,终端中的用户已提交一行时才会收到任何输入。因此,删除是终端的一项功能,而不是您的程序。
答案 1 :(得分:1)
除非你把终端放在&#34; raw&#34;模式,操作系统不会向应用程序提供输入,直到您按回车键。输入编辑由操作系统处理。当你调用getchar()
时,它会从这个输入缓冲区读取一个字符,而不是直接从终端读取。
POSIX函数getline()
执行相同的操作。