有没有一种方法可以“动态调整” char变量的大小?

时间:2019-12-10 16:32:06

标签: c arrays character

我不完全知道如何用短语表达问题。有没有办法让我输入的每个字符都变得更大?这有点难以理解。看一下代码:

char t[100];
scanf("%c", &t);

如果需要,是否有办法使char大于100个索引?

1 个答案:

答案 0 :(得分:1)

是,但是...

您无法在示例中调整大小固定为t的数组。您必须使用malloccallocrealloc之类的动态内存例程来分配缓冲区并调整其大小。这是一个典型的实现,它从一个小的缓冲区开始,并根据需要将其大小加倍:

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

/**
 * getInput 
 *
 * Reads input from the specified stream into a character buffer, extending
 * the buffer as necessary.
 *
 * Inputs: 
 * 
 *   stream - the input stream
 *
 * Outputs: none
 * 
 * Returns: pointer to a character buffer containing the input string.
 */
char *getInput( FILE *stream )
{
  /**
   * Track the physical size of our buffer, which is at least 1 greater 
   * than the number of characters stored in it.  Since we double the
   * buffer size on each realloc, this has to start as a non-zero value.
   */
  size_t buffer_size = 1;        

  /**
   * Track the number of characters read from the input stream.  Once this
   * count equals the buffer size, we need to extend the buffer.  
   */
  size_t characters_read = 0;   

  /**
   * Pointer to our dynamically-allocated buffer.
   */
  char *buffer = NULL;

  int c;

  /**
   * Read characters from the input stream until we hit a newline or EOF.
   */
  while ( ( c = fgetc( stream ) ) != EOF && c != '\n' )      
  {
    /**
     * Update the number of characters read.
     *
     * If the number of characters read equals the buffer size,
     * then we need to extend the buffer.  Typically, we double
     * the buffer size.
     */
    if ( ++characters_read == buffer_size )    
    {
      /** 
       * Double the size of the buffer (if the buffer pointer is NULL, 
       * this will allocate the buffer).  ALWAYS assign the result of
       * realloc to a temporary pointer - if it fails, it will return NULL
       * and leave the buffer unchanged.  If you assign that NULL to your
       * pointer variable, you'll lose your reference to that memory.
       */
      char *tmp = realloc( buffer, sizeof *buffer * (buffer_size * 2) );

      /**
       * If the allocation is unsuccessful, write an error message and
       * return the buffer in its current state.
       */
      if ( !tmp )
      {
        fprintf( stderr, "getInput - failed to extend input buffer, returning what we have so far...\n" );
        return buffer;
      }

      /**
       * Otherwise, update our buffer pointer (which may have changed
       * as a result of the malloc operation) and buffer size:
       */
      buffer = tmp;
      buffer_size *= 2;
    }

    /**
     * Write the character to the buffer.  Remember that arrays are
     * 0-indexed, so the first character goes to index 0, second
     * character goes to index 1, etc.
     */
    buffer[characters_read-1] = c;
  }
  /**
   * Terminate the string.  The logic above should make sure that
   * characters_read is *always* less than buffer_size, so we shouldn't
   * need to check for overflow here.
   */
  buffer[characters_read] = 0;

  /**
   * Some debugging output
   */
  fprintf( stderr, "buffer_size = %zu\n", buffer_size );
  fprintf( stderr, "characters_read = %zu\n", characters_read );

  return buffer;
}

/**
 * Simple main program to exercise the code above.
 */
int main( void )
{
  printf( "Gimme something: " );
  char *input = getInput( stdin );
  if ( input )
  {
    printf( "You typed: \"%s\"\n", input );
    free( input );
  }
  else
  {
    printf( "error getting input\n" );
  }
  return 0;
}

一些示例运行:

jbode:input john.bode$ ./input
Gimme something: a
buffer_size = 2
characters_read = 1
You typed: "a"

jbode:input john.bode$ ./input
Gimme something: ab
buffer_size = 4
characters_read = 2
You typed: "ab"

jbode:input john.bode$ ./input
Gimme something: abc 
buffer_size = 4
characters_read = 3
You typed: "abc"

jbode:input john.bode$ ./input
Gimme something: abcd
buffer_size = 8
characters_read = 4
You typed: "abcd"

请注意,缓冲区大小始终至少比字符串中的字符数大1。

每次结束时将缓冲区的大小加倍,最终比每次将其扩展固定量的运行时效率高一点,因为平均而言,您进行的realloc调用较少(是一项昂贵的操作)。折衷方案是您可能会得到一个缓冲区,其大小是实际需要的两倍。扩展固定的数量将导致更少的空间浪费,但是请参见上面的运行时。最后,您可能需要做一些分析,以确定哪种方法最适合当前的问题。