Better than scanf

I don't know how to do this:

printf("creazione nuovo messaggio\n");
             printf("insert dest\n");
             scanf("%s",dest);
             printf("insert object\n");
             scanf("%s",ogg);
             printf("inserire text\n");
             scanf("%s",test);
             printf("%s\n",dest);
             printf("%s\n",ogg);
             printf("%s\n",test);
             strcpy(messaggio,dest);
             strcat(messaggio,"/");
             strcat(messaggio,ogg);
             strcat(messaggio,"/");
             strcat(messaggio,test);
             strcat(messaggio,"/");
             printf("%s",messaggio);

For example it do this:

dest=jonny
ogg=hello
test=how are you

and it prints

jonny
hello
how

why doesn't it print all that I write but only the first word:confused:

Because that's the behaviour of that function - according to the man page, %s matches "a sequence of non-white-space characters". If I remember correctly, you should see the terminating new line if it's there in the input. So, all you have to do to read a sequence of characters that includes whitespace is put scanf() in a while() loop that exits once it's spotted a newline. Although you *may* have to use getchar() to skip past whitespace... I'm not too familiar with this family of functions.

Either way, if you play around a bit it shouldn't be too hard.

---------- Post updated at 07:29 AM ---------- Previous update was at 07:23 AM ----------

Oh yeah, I should have mentioned - a perhaps-easier alternative would be to use a regex-style set, e.g:

scanf("%[a-zA-Z0-9 ]", test);

to allow all numbers, letters and a space.

(NOT TESTED)

Thank you very much!
Here is the exactly code to read whitespaces too:

             puts("insert text ");
             while(getchar()!=(int)'\n');
             scanf("%[^\t\n]",test);
             puts(test);

You could also use fgets, which always retrieves an entire line:

char buf[512];
printf("Input something: ");
fgets(buf, 512, stdin);

It gives you the entire string including the return character though! :slight_smile: So:

char buf[512];

printf("Input something: ");
if(fgets(buf, 512, stdin) != NULL)
{
        size_t pos=strlen(buf);
        if(pos > 0)
        {
                if(buf[pos-1]) == '\n') buf[pos-1]='\0';
        }
}

This will input an entire line and chop the newline off the end.

Thank you Corona! But it's a little bit difficoult then the other!I'll try it but I think I'll use the other... :wink:

scanf may be easier(or at least more obvious) but will cause strange problems -- as you've already seen. And there's others too. Try this:

#include <stdio.h>

int main(void)
{
        int fail=1, n;
        while(fail)
        {
                fail=0;

                printf("\nPlease enter a number: ");
                if(scanf("%d", &n) != 1)
                        fail=1;
        }

        printf("You input %d\n", n);
        return(0);
}

When you enter a number, it works fine. When you enter qwertyuiop, it goes into an infinite loop. This is because scanf only reads one single character, finds that it's not a number, gives up, and puts it back so the data you get the next loop is the same you had last time. You have to fflush(stdin); to get rid of the backed-up garbage.

If you're inputting whole lines, scanf is the wrong function to use.

Often I use fgets and scanf together to avoid that buffer-problem, like this:

char buf[512];
int n;
// Read in an entire line
fgets(buf,512,stdin);
// scan the string for the data you want
sscanf(buf, "%d", &n);

Note the extra s, that's intentional. sscanf works just like scanf except it scans strings. This way, if scanf has an error, the data won't remain stuck in the buffer until flushed since it's already been read.

Mmm very good idea!! I'll try it ;-)!

yes, scanf is really pants, avoid it when you can.
it's better to read the line and parse it afterwards.