Keith Miller
Keith Miller

Reputation: 1347

scanf dynamic allocation

For whatever reason the following code prints (null):

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

int main(void)
{
    char *foo; 
    scanf("%ms", &foo);
    printf("%s", foo);
    free(foo);
}

I'm trying to allocate memory for a string dynamically but as I said earlier my program simply outputs (null). I worked around this by making a function using getche and realloc but it seems almost pointless due to the fact that I also had to program what would happen if the user entered backspace, tab, etc.. But as I said that is just a work around and I would rather know why the above code is not working...

Additional Information:

I am using the Pelles C IDE v7.00 and compiling with the C11 standard

Upvotes: 11

Views: 21190

Answers (5)

Steve
Steve

Reputation: 11

There is an example in the man page for scanf/sscanf (page 3, from line 270-290) that states the following:

EXAMPLE

To use the dynamic allocation conversion specifier, specify m as a length modifier (thus %ms or %m[range]). The caller must free(3) the returned string, as in the following example:

char *p;
int n;

errno = 0;
n = scanf("%m[a-z]", &p);
if (n == 1) {
   printf("read: %s\n", p);
   free(p);
} else if (errno != 0) {
   perror("scanf");
} else {
   fprintf(stderr, "No matching characters\n");
}

As shown in the above example, it is necessary to call free(3) only if the scanf() call successfully read a string.

Source: SCANF(3) - Linux Programmer's Manual - GNU - 2013-01-30

Upvotes: 1

ulatekh
ulatekh

Reputation: 1490

%m is a POSIX extension, which may be why it's not available in Pelles C.

Upvotes: 2

zhangjie
zhangjie

Reputation: 341

as Arun says, this solution is right and Meninx's opinion is wrong:

char *s;
scanf("%ms", &s);
printf("%s", s);
free(s);

I have read the 'man scanf', it says:

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.

Upvotes: 0

Arun
Arun

Reputation: 2478

I am using Linux 3.2.0 amd 64 with gcc 4.7.2. Using the code:

char *s; 
scanf("%ms", &s);
printf("%s", s);
free(s);

works fine but it won't accept whitespaces.

For static allocation, you can instead use:

char s[100];
printf("Enter string (max 99 characters): ");
scanf("%100[^\n]s", &s);
printf("You entered: %s\n", s);

Hope it helps!

Upvotes: 0

Norman Ramsey
Norman Ramsey

Reputation: 202595

I am not seeing %m in section 7.21.6.2 of the Draft C11 standard (the section on fscanf). I suggest that you avoid it and call malloc() as you would in C99.

Upvotes: 9

Related Questions