动态分配输入字符串

时间:2017-01-16 21:30:17

标签: c arrays realloc dynamic-allocation

我编写了以下函数来在输入时动态分配输入字符串,而不会询问用户多长的字符数。

#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);
*/

此代码有效,但我对此有一些疑问:

  1. 为什么会这样? 我不明白为什么,当我执行它时,我也可以在按Enter键之前删除字符。 getchar()函数在每次迭代时只读取一个字符,这个字符写入数组,所以我怎么能删除一些呢? 如果getchar()在收到'\ 127'时删除了前一个字符,那么循环应该像任何其他字符一样继续执行。但这不会发生,因为当循环结束时,“i”总是包含确切数量的元素。

  2. 我的代码有效吗?如果不是,我怎么能做得更好(甚至使用内置功能)?

2 个答案:

答案 0 :(得分:1)

回答第一个问题:

原因可能是终端驱动程序中的缓冲。注释部分提供了一个简短的解释here0x000001bd76170c44: 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)

  1. 除非你把终端放在&#34; raw&#34;模式,操作系统不会向应用程序提供输入,直到您按回车键。输入编辑由操作系统处理。当你调用getchar()时,它会从这个输入缓冲区读取一个字符,而不是直接从终端读取。

  2. POSIX函数getline()执行相同的操作。