views:

87

answers:

5

My question is exactly the same as this one. That is, I'm trying to use scanf() to receive a string of indeterminate length, and I want scanf() to dynamically allocate memory for it.

However, in my situation, I am using VS2010. As far as I can see, MS's scanf() doesn't have an a or m modifier for when scanning for strings. Is there any way to do this (other than receiving input one character at a time)?

A: 

I think, in real world, one need to have some maximum limit on length of user input.

Then you may read the whole line with something like getline(). See http://www.cplusplus.com/reference/iostream/istream/getline/

Note that, if you want multiple input from user, you don't need to have separate char arrays for each of them. You can have one big buffer, e.g. char buffer[2048], for using with getline(), and copy the contents to a suitably allocated (and named) variable, e.g. something like char * name = strdup( buffer ).

ArunSaha
It is probably better to let `getline()` allocate a buffer for you, if the buffer is not big enough then `getline()` will make it big enough.
Frank
+2  A: 

Must you absolutely use scanf ? Aren't std::string s; std::cin >> s; or getline( std::cin, s ); an option for you?

usta
+1  A: 

Don't use scanf for reading strings. It probably doesn't even do what you think it does; %s reads only up until the next whitespace.

R..
Don't be like that, your "answer" is not helpful. This guy does probably not have the man pages lying around and is asking for how he should do - not how he should **not**.
Frank
@Frank: I thought the point about `%s` and whitespace was a rather astute observation!
Jim Lewis
Yes, you are right, but maybe the guy know that %s does only read up to the next whitespace like std::cin does. High might have some code that has previously compiled on a *nix/GNU system before and tries to get it running on his vc10.It would be easier if we/he had some existing code to work on/show.
Frank
My first sentence stands alone; the second is just extra commentary.
R..
A: 

If you want to use scanf you could just allocate a large enough buffer to hold any possible value, say 1024 bytes, then use a maximum field width specifier of 1024.

The m and a are specific non-standard GNU extensions, so thats why Microsofts compiler does not support them. One could wish that visual studio did.

Here is an example using scanf to read settings, and just print them back out: #include #include #include

int
main( int argc, char **argv )
{   // usage ./a.out < settings.conf

    char *varname;
    int value, r, run = 1;

    varname = malloc( 1024 );

    // clear errno
    errno = 0;

    while( run )
    {   // match any number of "variable = #number" and do some "processing"

        // the 1024 here is the maximum field width specifier.
        r = scanf ( "%1024s = %d", varname, &value );
        if( r == 2 )
        {   // matched both string and number
            printf( " Variable %s is set to %d \n", varname, value );
        } else {
            // it did not, either there was an error in which case errno was
            // set or we are out of variables to match
            if( errno != 0 )
            {   // an error has ocurred.
                perror("scanf");
            }
            run = 0;
        }
    }

    return 0;
}

Here is an example settings.conf

cake = 5
three = 3
answertolifeuniverseandeverything = 42
charcoal = -12

You can read more about scanf on the manpages.

And you can of course use getline(), and after that parse character after character.

If you would go into a little more what you are trying to achieve you could maybe get an better answer.

Frank
I would explain how to write a field width specifier, since OP is likely not to know and just to ignore the advice, creating a buffer overflow vulnerability...
R..
Right, I probably should. But what does OP stand for?
Frank
+3  A: 

Standard versions of scanf() do not allocate memory for any of the variables it reads into.

If you've been hoodwinked into using a non-standard extension in some version of scanf(), you've just had your first lesson in how to write portable code - do not use non-standard extensions. You can nuance that to say "Do not use extensions that are not available on all the platforms of interest to you", but realize that the set of platforms may change over time.

Jonathan Leffler
+1 for pointing out how relying on non-portable extensions has bit the OP.
R..