Search code examples
cinputsizebuffergets

Reading strings in C


If I was using C gets(), and I was reading a string from the user, but I have no idea how big of a buffer I need, and the input could be very large. Is there a way I can determine how large the string the user inputted was, then allocate memory and then put it in the variable? Or at least a way to accept input without knowing how large it is, with a possibility it won't fit in the buffer i've already allocated.


Solution

  • I think use an intermediate buffer which is suitably large, and input the string into it with fgets or other function by limiting the string length to the max buffer size. Later when the string is input,. calculate the string length and allocate a buffer of the size of the string and copy it into the newly allocated buffer. The old large buffer can be reused to such inputs.

    You can do:

    fgets (buffer, BUFSIZ, stdin);

    or

    scanf ("%128[^\n]%*c", buffer);

    Here you can specify the buffer length 128 bytes as %128.. and also include all the blankspace within the string.

    And then calculate the length and allocate new buffer with:

    len = strlen (buffer);
    string = malloc (sizeof (char) * len + 1);
    strcpy (string, buffer);
    .
    .
    .
    free (string);
    

    EDIT

    Here is one way i worked out:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (void)
    {
      char *buffer[10];  /* temporary buffers 10 nos, or make this dynamically allocated */
      char *main_str;    /* The main string to work with after input */
      int k, i=0, n, retval;
    
      while (1)
      {
        buffer[i] = malloc (sizeof (char) * 16); /* allocate buffer size 16 */
        scanf ("%15[^\n]%n", buffer[i], &n);     /* input length 15 string + 1 byte for null */
        if (n<16)                                /* Buffer is not filled and end of string reached */
          break;
        n=0;                                     /* reinitialize n=0 for next iteration. to make the process work if the length of the string is exactly the sizeof the buffer */
        i++;
      }
      /* need to fix the while loop so that the buffer array does not overflow and protect it from doing so */
    
      /* allocate buffer of exact size of the string */
      main_str = malloc (sizeof (char) * 16 * i + strlen (buffer[i]));
    
      /* copy the segmented string into the main string to be worked with 
       * and free the buffers
       */
      strcpy (main_str, "");
      for (k=0; k<=i; k++)
      {
        strcat (main_str, buffer[k]);
        free (buffer[k]);
      }
    
      /* work with main string */
      printf ("\n%s", main_str);
    
      /* free main string */
      free (main_str);
    
      return 0;
    }
    

    You need to fix the code to stop crashing in some cases, but this should answer your question.