Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to input a string with unknown size

I'm a bit confused about strings in C. I understand that declaring buffer size is important since otherwise, it can cause buffer overflow. But I need to know how do I take a string input that I don't know the size of. For instance, if I wanted to take a line of text from the user as input and I had no way of knowing how long their text would be, how do I do it?

I've tried dynamically allocating memory as the user gives an input. Here's the code-

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

int main()
{
    char *str, ch;
    int size = 10, len = 0;
    str = realloc(NULL, sizeof(char)*size);
    if (!str)return str;
    while (EOF != scanf_s("%c", &ch) && ch != '\n')
    {
        str[len++] = ch;
        if (len == size)
        {
            str = realloc(str, sizeof(char)*(size += 10));
            if (!str)return str;
        }
    }
    str[len] = '\0';
    printf("%s\n", str);
    free(str);
}

The problem is, when I compile it using VS-2017, I get these errors-

source.c(10): warning C4473: 'scanf_s' : not enough arguments passed for format string

source.c(10): note: placeholders and their parameters expect 2 variadic arguments, but 1 were provided

source.c(10): note: the missing variadic argument 2 is required by format string '%c'

source.c(10): note: this argument is used as a buffer size

I think that dynamically allocating memory as I go on(like in the above code) should work, but I'm probably doing something wrong. Is there a way to make this work?

EDIT: Word.

like image 511
Chase Avatar asked Nov 02 '18 09:11

Chase


People also ask

How do you take string input of an unknown length in C?

For this problem, there is a format specifier %s by which we can read a string of unknown length and we don't need looping to read and print the string in the code. It results in less time taken for compiling the code by the compiler.

How do you input a string of specified length?

Just use it like this: char str[1000]; scanf("%s",str); You can take input of a string of length upto 999 characters as last character is used for storing null character.

How do you input a string with blank spaces?

Follow these rules when you specify an input string that has blank spaces or quotation marks: If the input string has one or more spaces, enclose the string with either single or double quotation marks. You can use single or double quotation marks, as long as they match.

Can I declare a string without size in C?

A string in C is nothing more than a character array with the character \0 to define the end of it. Since it is an array, it requires storage and therefore you cannot "define" it without storage.


2 Answers

  1. You should use getchar not scanf_s
  2. You should use int ch; not char ch; for EOF

The following code could work:

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

int main() {
    char *str = NULL;
    int ch;
    size_t size = 0, len = 0;

    while ((ch=getchar()) != EOF && ch != '\n') {
        if (len + 1 >= size)
        {
            size = size * 2 + 1;
            str = realloc(str, sizeof(char)*size);
        }
        str[len++] = ch;
    }
    if (str != NULL) {
        str[len] = '\0';
        printf("%s\n", str);
        free(str);
    }

    return 0;
}
like image 105
Yunbin Liu Avatar answered Oct 12 '22 10:10

Yunbin Liu


  • scanf_s requires a buffer size as argument, and you don't want that
  • Generally scanf will read from stdin once the \n is fed anyways.
  • Using getchar here is a better approach

Here is a version using getchar:

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

int     main()
{
  char  *str = NULL;
  int   ch;
  int   capacity = 10, size = 0;

  str = realloc(str, sizeof(*str) * (capacity + 1));
  if (!str) return 1;
  while ((ch = getchar()) != EOF && ch != '\n')
    {
      if (size == capacity)
      {
        capacity += 10;
        str = realloc(str, sizeof(*str) * (capacity + 1));
        if (!str) return 1;
      }
      str[size] = (char)ch;
      size++;
    }
  str[size] = '\0';
  printf("%s\n", str);
  free(str);
  return 0;
}
like image 44
Tezirg Avatar answered Oct 12 '22 11:10

Tezirg