Reputation: 703
I would like to know if there is any way to dynamically allocate some memory when/before using a scanf. This would mean that there is no need to give a char *
a size when initializing it. Instead of this, the quantity of memory needed would be allocated depending on the size of the input string (which means: after having the input).
Currently I find no other solution than to allocate a specific quantity of memory before having the input, so before knowing the size of the input:
char str[10];
scanf("%s", str);
And I know this is not safe: if the input is longer than 10 characters, the program will write on unallocated memory, which can cause segfaults or stuff like that.
Upvotes: 1
Views: 2627
Reputation: 154280
User input from stdin
is tricky.
OP's "if the input is longer than 10 characters, the program will write on unallocated memory" is an off-by 1 problem. If input is longer than 9, the program will attempt to write outside str[]
.
char str[10];
scanf("%s", str); // Trouble with input more than 9
getline();
, as suggested by this good answer is the typical solution.
I am rejecting the idea of "dynamic allocation during a scanf" as a good design goal. A program that allows for endless input is prone to abuse. It allows the user to overwhelm system resources. Good code validates input first. No more Heartbleed.
Instead I recommend that stdin
input is assessed for a reasonable input length, be it 10, 1000, or 1,000,000 and a buffer of 2x or so is provided.
#define MAX_EXPECTED_SIZE 100
char buf[MAX_EXPECTED_SIZE * 2];
if (fgets(buf, sizeof buf, stdin)) {
size_t len = strlen(buf);
if (len + 1 == sizeof buf && buf[len] != '\n') {
// Assume hostile input and act accordingly. Possibly exiting with message.
// or consume rest of line
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
return ERROR_LONG_LINE
}
// Use buf[]
}
Code can allocate the right-sized memory afterward if a copy of buf
needs to be retained.
Upvotes: 1
Reputation: 4044
As pointed in comments, %m I believe solves your query
Another approach will be to limit the input to number byte you know you have allocated to your variable with eg %10s will input only 10 characters Then reallocating your input variable to make room for more character to be input in next call to scanf, you need to pass str like &str[10] in next call so that it does not overwrite earlier input
Upvotes: 1
Reputation: 5950
Use the getline function,
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
Example Try Online
int main(void)
{
char * line;
size_t size;
if(getline(&line, &size, stdin) != (-1))
{
printf("You entered: %s",line);
}
return 0;
}
Upvotes: 0