Home > Software design >  As I create a string in C with the exact size of the word entered by console
As I create a string in C with the exact size of the word entered by console

Time:10-14

I am new to C and I was wondering how I can do so that when a word of X characters is entered through the console, an array of characters is created with the right memory allocation for it, for example I enter "hello" and it is saved in a string of 6-space characters.Thanks!

CodePudding user response:

There is nothing in the ISO C standard library specification or Microsoft C library that directly does what you seek.

In the C POSIX library, however (what's the difference?), the scanf family of functions support an m modifier for string s inputs. When m is used, scanf() will allocate a buffer of an appropriate size, and assign it to the pointer that you provide:

From the Linux scanf() man page:

An optional 'm' character. This is used with string conversions (%s, %c, %[), and relieves the caller of the need to allocate a corresponding buffer to hold the input: instead, scanf() allocates a buffer of sufficient size, and assigns the address of this buffer to the corresponding pointer argument, which should be a pointer to a char * variable (this variable does not need to be initialized before the call). The caller should subsequently free(3) this buffer when it is no longer required.

Here's an example:

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

int main(void)
{
    char *input = NULL;

    if (scanf("%ms", &input) != 1) {
        fprintf(stderr, "scanf() failed\n");
        return 1;
    }

    printf("scanf() allocated string: \"%s\"\n", input);

    free(input);

    return 0;
}

Supported C libraries:

Unsupported C libraries:

CodePudding user response:

Looked interesting to try to directly meet OP's goal of <enter "hello" and it is saved in a string of 6-space character> using standard library functions, even if it took some code.

Sadly standard C does not offer the nice option as suggested with @Jonathon Reinhart good answer.

Instead, below is an approach not suited for learners, but does the job. It does not have a prior line length limit. It recursively forms a link list of characters entered (recursion not suitable for a long line), then allocates an array based on depth, and assigns the array.

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

typedef struct link_s {
  struct link_s *prev;
  char ch;
} llink;

char* foo(llink *prior) {
  int ch = fgetc(stdin);
  if (ch == '\n' || ch == '\r' || ch == EOF) {
    llink *ll = prior;
    size_t len = 1;
    while (ll) {
      len  ;
      ll = ll->prev;
    }
    char *buf = malloc(len);
    if (buf) {
      buf[--len] = '\0';
      llink *ll = prior;
      while (ll) {
        buf[--len] = ll->ch;
        ll = ll->prev;
      }
    }
    return buf;
  }
  llink node = {.prev = prior, .ch = (char) ch};
  return foo(&node);
}

int main() {
  char *s = foo(NULL);
  printf("<%s>\n", s);
  free(s);
  return 0;
}

Input

Hello<enter>

Output

<Hello>

CodePudding user response:

If you only need to read until a newline, you can use getline defined in stdio.h. It does automatic memory allocation. The function will allocate an extra character to store the newline, you can remove it using buf[strcspn(buf, '\n')] = '\0'.

If you want it to read until a whitespace, sad to say there's no standard C library function to meet your needs for arbitrary string lengths (without writing a bunch of your own code). If you are a beginner learning C and need simple I/O, using scanf("%s", buf) into a fixed sized buffer should be plenty.

  •  Tags:  
  • c
  • Related