Dynamically query a row without knowing the size of the row

In C, what is the best way to call and save a string without wasted space if we cannot query the length of the string. For example, usually I would do something like the following ...

char fname[30];
char lname[30];

printf("Type first name:\n");
scanf("%s", fname);

printf("Type last name:\n");
scanf("%s", lname); 

printf("Your name is: %s %s\n", fname, lname);

However, I am annoyed by the fact that I should use more space than necessary, so I do not want to use it char fname[30], but instead dynamically allocate the size of the string. Any thoughts?

+4
source share
2 answers

You can create a function that dynamically allocates memory for input as a user, using getchar()to read one character at a time.

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

void* safeRealloc(void* ptr, size_t size) {
  void *newPtr = realloc(ptr, size);
  if (newPtr == NULL) { // if out of memory
    free(ptr); // the memory block at ptr is not deallocated by realloc
  }
  return newPtr;
}

char* allocFromStdin(void) {
  int size = 32; // initial str size to store input
  char* str = malloc(size*sizeof(char));
  if (str == NULL) {
    return NULL; // out of memory
  }
  char c = '\0';
  int i = 0;
  do {
    c = getchar();
    if (c == '\r' || c == '\n') {
        c = '\0'; // end str if user hits <enter>
    }
    if (i == size) {
        size *= 2; // duplicate str size
        str = safeRealloc(str, size*sizeof(char)); // and reallocate it
        if (str == NULL) {
          return NULL; // out of memory
        }
    }
    str[i++] = c;
  } while (c != '\0');
  str = safeRealloc(str, i); // trim memory to the str content size
  return str;
}

int main(void) {
  puts("Type first name:\n");
  char* fname = allocFromStdin();

  puts("Type last name:\n");
  char* lname = allocFromStdin();

  printf("Your name is: %s %s\n", fname, lname);

  free(fname); // free memory afterwards
  free(lname); // for both pointers
  return 0;
}
+3
source

man scanf:

• "m". (% s, % c,% [) : scanf() , char * ( ). (3) , .

, , POSIX ( fiddling_bits).

, , , :

char *alloc_answer() {
  char buf[1000];
  fgets(buf,sizeof(buf),stdin);
  size_t l = strlen(buf);
  if (buf[l-1]=='\n') buf[l]=0; // remove possible trailing '\n'
  return strdup(buf);
}

1000 ( , ).

...

+3

All Articles