C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 09-09-2009, 09:57 AM   #1
Registered User
 
Join Date: Sep 2009
Posts: 10
Question scanf return values

hi guys,

ok, i just realised something about scanf and its return values. when a user tries to assign (for example) three values to three variables, the return value of scanf is 3. nice.
THEN, if the user decides to input 4 values, return value of scanf is still three (since it reads only first three of them). where has the fourth value gone?
I'd like the user to be forced to input just three numbers by using:
Code:
if ((scanf("%lf%lf%i", &num1, &num2, &num3)) == 3)
{
       //some more of these calculations
}

else
{
      printf("Wrong number of arguments\n");
      return 1;
}
but that does not work. if i give 4 values, programme gives no errors and carries on with calculations.

how would i restrict user to input only 3 values otherwise? is that a normal behavior for scanf?
pirog is offline   Reply With Quote
Old 09-09-2009, 10:01 AM   #2
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,365
Quote:
Originally Posted by pirog
THEN, if the user decides to input 4 values, return value of scanf is still three (since it reads only first three of them). where has the fourth value gone?
The fourth value remains in the input buffer.

Quote:
Originally Posted by pirog
how would i restrict user to input only 3 values otherwise?
You could read in the whole line and parse it using say, sscanf().
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 09-09-2009, 10:17 AM   #3
Registered User
 
Join Date: Sep 2009
Posts: 10
Thanks laselight,

i think it is an unnecessary use of input buffer. do extra values keep on filling up buffer and can this buffer overflow (if the number given to it is too large, for example)?

hmmm, reading the line and then parsing through sscanf()? i thought scanf() would do a similar job without the need of scanning the whole input line. well, I am not even a moderate (yet) programmer myself, but I'll try your solution.

yet, what bugs me, is that scanf can only give me first three values and not the actual number of values i provided. Makes IF statement redundant! heh.

thanks anyway.
pirog is offline   Reply With Quote
Old 09-09-2009, 10:20 AM   #4
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,365
Quote:
Originally Posted by pirog
yet, what bugs me, is that scanf can only give me first three values and not the actual number of values i provided. Makes IF statement redundant! heh.
What happens if the user only enters two values?
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 09-09-2009, 10:26 AM   #5
Registered User
 
Join Date: Sep 2009
Posts: 10
laserlight,

actually, the programme waits until i enter at least 3 values. even if i separate them by X number of CARRIAGE RETURNS. Of course the programme (however small) terminates on the account of any letters. i guess that's typical of SCANF().
pirog is offline   Reply With Quote
Old 09-09-2009, 10:48 AM   #6
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,365
To enter just two values, enter them, then simulate EOF (e.g., CTRL + Z or CTRL + D).
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is online now   Reply With Quote
Old 09-09-2009, 11:01 AM   #7
Registered User
 
Join Date: Sep 2009
Posts: 10
while running this programme in the terminal and pressing C-Z or C-D gives me russian letters (my keyboard is set to Eng/Rus). Anyway, the following ensures such termination and gives my own error message:
Code:
	if (n != EOF)
		printf("Warning: Input reading terminated by error.\n");
where n is my SCANF() return value
but i am not worried about the user inputting only two values (the above takes care of that). it is him putting 4 values, that still results in return value of SCANF() to be 3. I think it is a shame for scanf to take on predetermined number of arguments.

i am still to implement your solution involving SSCANF() - doing somehting else at the moment.
pirog is offline   Reply With Quote
Old 09-11-2009, 04:09 PM   #8
Registered User
 
Join Date: Sep 2009
Posts: 10
Tried to implement the SSCANF suggestion, but unsuccessfully.
From what errors I could unscramble, the issue was in an incorrect formating. I am going to stick to SCANF routine, although I still think it is not so beautiful.

thanks for help anyway
pirog is offline   Reply With Quote
Old 09-11-2009, 04:56 PM   #9
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
You can't just use sscanf() as a drop-in replacement for scanf(). sscanf() parses its tokens from a char[] array rather than from stdin. So the general idea is that you use fgets() or a similar function to read data into a buffer, and then use sscanf() to parse that buffer. Quick example:
Code:
#include <stdio.h>

int main() {
    char buffer[BUFSIZ];
    int x, y, z;
    
    printf("Enter exactly three numbers on one line:\n");
    for(;;) {
        int bogus;
        
        if(!fgets(buffer, sizeof buffer, stdin)) return 1;
        
        if(sscanf(buffer, "%d%d%d%d", &x, &y, &z, &bogus) != 3) {
            printf("Hey. I said *exactly* three numbers.\n");
        }
        else break;
    }
    
    printf("Product %d*%d*%d = %d\n", x, y, z, x*y*z);
    
    return 0;
} 
Example run:
Code:
Enter exactly three numbers on one line:
1 2
Hey. I said *exactly* three numbers.
1 2 3 4
Hey. I said *exactly* three numbers.
1 2 3
Product 1*2*3 = 6
There are other ways to see if the user entered data beyond what you expected. You could use %p to see how far sscanf() read and then see if there were any non-space characters between there and the end of the string (or just use %c to make your life a lot easier).
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 09-12-2009, 02:25 AM   #10
Registered User
 
Join Date: Sep 2009
Posts: 10
Thanks for such an informative reply, DWKS!!!

I shall certainly try it your way, but as far as i can see that pretty much answers my question.
What i was doing, as you probably understood from previous posts, was using SSCANF just as I would use SCANF. Of course, I couldn't make getc to work either and was left to use scanf's buffer and that basically defeats the purpose of SSCANF.

Thanks a lot. I'll keep you posted on my progress.
pirog is offline   Reply With Quote
Old 09-12-2009, 04:03 AM   #11
Registered User
 
Join Date: Sep 2009
Posts: 10
dwks,

the example you've given worked like a charm. Although i did not get the idea behind bogus variable, but then it came to me that it is a dummy variable and is necessary for the limitation of user input.
Couldn't define BUFFSIZE in pre-processor and then use it in CHAR BUFF[BUFFSIZE], so i just set it in declaration CHAR BUFF[120]. Other than that, there were no probs with the example.

Only thing left is to apply the solution to my programme.

Thanks a lot!
pirog is offline   Reply With Quote
Old 09-12-2009, 09:42 AM   #12
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,629
Quote:
Although i did not get the idea behind bogus variable, but then it came to me that it is a dummy variable and is necessary for the limitation of user input.
Yes, "dummy" would perhaps have been a better name. Oh well.

Quote:
Couldn't define BUFFSIZE in pre-processor and then use it in CHAR BUFF[BUFFSIZE], so i just set it in declaration CHAR BUFF[120]. Other than that, there were no probs with the example.
BUFSIZ is pre-defined in stdio.h to be something at least 512. It's a good size to use for buffers. If you want to use your own size, of course, you could say #define BUFFER_SIZE 120 or something -- but don't try to re-define BUFSIZ, since the compiler probably won't like that too much.
__________________
dwk

Seek and ye shall find. quaere et invenies.

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell


Other boards: DaniWeb, TPS
Unofficial Wiki FAQ: cpwiki.sf.net

My website: http://dwks.theprogrammingsite.com/
Projects: codeform, xuni, atlantis, etc.

New project: nort
dwks is offline   Reply With Quote
Old 09-12-2009, 03:06 PM   #13
Registered User
 
Join Date: Sep 2009
Posts: 10
hey dwks,

i defined BUFFSIZE in a pre-processor statement as you have it in your last post, but my compiler did not like it. not quite sure why (i might have a look at it later), but that's the reason i defined it in declaration of CHAR BUFF[120]

i took a liberty of looking at your webpage, it looks good - i might visit it for reference purposes

good luck

p.s. still, i am left to implement your solution in my programme (when i get a chance)
pirog is offline   Reply With Quote
Old 09-12-2009, 03:44 PM   #14
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 8,740
Quote:
Originally Posted by pirog View Post
hey dwks,

i defined BUFFSIZE in a pre-processor statement as you have it in your last post, but my compiler did not like it. not quite sure why (i might have a look at it later), but that's the reason i defined it in declaration of CHAR BUFF[120]

i took a liberty of looking at your webpage, it looks good - i might visit it for reference purposes

good luck

p.s. still, i am left to implement your solution in my programme (when i get a chance)
I like guessing: don't put a semicolon at the end of your define (and don't put an equals sign in it either).
tabstop is offline   Reply With Quote
Old 09-12-2009, 04:11 PM   #15
Registered User
 
Join Date: Sep 2009
Posts: 10
hey tabstop,

i did not keep the backup of it (since that was a trial file, although i do in general) but i did not use the equal sign.
Yet, I am pretty sure i had a semicolon in there

appreciated!
thanks to everyone for their input.
pirog is offline   Reply With Quote
Reply

Tags
return_value, scanf

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
How can I make this code more elegant? ejohns85 C++ Programming 3 04-02-2009 08:55 AM
DirectInput help Muphin Game Programming 2 09-10-2005 11:52 AM
Pong is completed!!! Shamino Game Programming 11 05-26-2005 10:50 AM
problem with open gl engine. gell10 Game Programming 1 08-21-2003 04:10 AM
Algorithm to walk through a maze. Nutshell C Programming 30 01-21-2002 01:54 AM


All times are GMT -6. The time now is 07:49 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22