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.
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.
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.
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.
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.
getchar
not scanf_s
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;
}
scanf_s
requires a buffer size as argument, and you don't want thatscanf
will read from stdin
once the \n
is fed anyways.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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With