在 C 中使用 realloc 按字符读取输入字符

Reading input char by char using realloc in C

我想逐个读取输入的字符并将其作为一个单词保存到 char* 数组中。我不知道输入会有多长时间,所以我想动态分配内存。当 char 为空白时,程序结束。我怎样才能使用 realloc 做到这一点? 有我的代码:

#include <stdio.h>
int main(void) {
    char *word=malloc(1*sizeof(char));
    char c;
    int numOfChars=0;
    c=getchar();
    word[0]=c;
    numOfChars++;
    while((c=getchar())!=' '){
        numOfChars++;
        realloc(word,numOfChars);
        word[numofChars-1]=c;
    }
    printf("%s", word);

    return 0;
}

示例输入:Word 示例输出:Word

这样就可以了

#include <stdio.h>
#include <stdlib.h>
int main(void) {
  char *ptr;
  char *word=malloc(1*sizeof *word);
  char c;
  int numofChars=0;
  printf("Enter string terminated by a space :");
  c=getchar();
  word[0]=c;
  numofChars++;

  while((c=getchar())!=' '){
    numofChars++;
    ptr=realloc(word,numofChars*sizeof *ptr);
    if(ptr!=NULL)
    {
      word=ptr;
      word[numofChars-1]=c;
    }
  }
  /* You need to append a null character to make it a valid string */
  numofChars++;
  ptr=realloc(word,numofChars*sizeof *ptr);
  if(ptr!=NULL)
  {
    word=ptr;
    word[numofChars-1]='[=10=]';
  }

  printf("Word : %s\n", word);

  free(word); // Freeing word/

  return 0;
}

嗯,你可以写一个函数来替换

 numofChars++;
      ptr=realloc(word,numofChars*sizeof *ptr);
      if(ptr!=NULL)
      {
        word=ptr;
        word[numofChars-1]='[=11=]';
      }

注: 不建议你这样做

  word=realloc(word,numOfChars*sizeof(char));

因为万一 realloc 失败,你就会有内存泄漏。所以我这里用了ptr

为了解释我的想法,我快速编写了这个小程序来解释如何使用指数增长:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define INITIAL_CAPACITY 100
#define GROW_FACTOR 1.5

struct string_buffer {
  size_t capacity;
  size_t length;
  char *buffer;
};

typedef struct string_buffer string_buffer_t;

string_buffer_t *sb_init(void);
static void sb_grow(string_buffer_t *sb);
void sb_shrink(string_buffer_t *sb);
char *sb_release(string_buffer_t *sb);

void sb_append_char(string_buffer_t *sb, char c);
char *sb_peek_string(string_buffer_t *sb);

int main(void)
{
  string_buffer_t *sb=sb_init();
  int c;

  while ( (c=getchar())!=' ' && c!='\n' && c!=EOF )
    sb_append_char(sb, c);

  char *string=sb_release(sb);
  printf("string : \"%s\"\nlength : %zu\n", string, strlen(string));
  free(string);
  return 0;
}

string_buffer_t *sb_init(void)
{
  string_buffer_t *new=malloc(sizeof *new);
  if (new==NULL) exit(EXIT_FAILURE);

  new->capacity=INITIAL_CAPACITY;
  new->length=1;
  new->buffer=malloc(INITIAL_CAPACITY);
  if (new->buffer==NULL) exit(EXIT_FAILURE);
  new->buffer[0]=0;

  return new;
}

static void sb_grow(string_buffer_t *sb)
{
  char *new=realloc(sb->buffer, (size_t) (GROW_FACTOR*sb->capacity));
  if (new==NULL) exit(EXIT_FAILURE);
  sb->capacity=(size_t) (GROW_FACTOR*sb->capacity);
  sb->buffer=new;
}

void sb_shrink(string_buffer_t *sb)
{
  char *new=realloc(sb->buffer, sb->length);
  if (new==NULL) exit(EXIT_FAILURE);
  sb->buffer=new;
}

char *sb_release(string_buffer_t *sb)
{
  sb_shrink(sb);
  char *string=sb->buffer;
  free(sb);
  return string;
}

void sb_append_char(string_buffer_t *sb, char c)
{
  if (sb->capacity==sb->length) sb_grow(sb);
  sb->buffer[sb->length-1]=c;
  sb->buffer[sb->length]=0;
  sb->length=sb->length+1;
}

程序可以如下所示。考虑到输入会被缓冲和填充,直到输入新行字符,该字符也是白色 space 字符。如果要使用格式说明符 %s 输出它,结果字必须以零结尾。

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

int main( void )
{
    int c;
    size_t n;
    char *word;
    char *tmp;

    n = 0;
    word = malloc( n + 1 );
    word[n++] = '[=10=]';

    printf( "Enter a word: " );

    while ( ( c = getchar() ) != EOF && !isspace( c ) && ( tmp = realloc( word, n + 1 ) ) != NULL )
    {
        word = tmp;
        word[n-1] = c;
        word[n++] = '[=10=]';
    }

    printf( "You've entered \"%s\"\n", word );

    free( word );
}        

程序输出可能看起来像

Enter a word: Hello
You've entered "Hello"