Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Programmer wannabee question about sscanf

Reply
Thread Tools

Programmer wannabee question about sscanf

 
 
broeisi
Guest
Posts: n/a
 
      03-04-2006
What advantages does sscanf offer over scanf?

I had the following code:

#include <stdio.h>
#include <string.h>

int main(void)
{
int start, finish, values;
char line[10];

memset(line,0, 10);

printf("Event numbers ? ");


fgets(line, sizeof(line), stdin);
values = sscanf(line,"%d %d", &start, &finish);

printf("start = %d en finish = %d values = %d\n",
start, finish, values);

return 0;
}

but if tha user inputted for example : erte 5 6 ..the output of start
and finished would not be 5 or 6 but some strange value...

I thought that sscanf would find values that are integers and assign
those integer values to the variables?

If not how can I accomplish this?

 
Reply With Quote
 
 
 
 
jhartzell42@gmail.com
Guest
Posts: n/a
 
      03-04-2006
sscanf does no more than scanf does; it just gets its input from a
string rather than from standard input. Both scanf and sscanf are
extremely strict; they expect input that would have been created by the
exact same formatting string using printf.
The most straight-forward way to get the first two numbers from a
string is to loop through the string, character by character, testing
each character to see if it is a digit. Then, when a digit is reached
(and you can, if you want, require and check that the digit either be
the first character in the string or preceded by whitespace) use strtol
to convert the number starting with that digit into the string.
strtol takes a pointer as its second argument, and will put a pointer
to the first character after the number into the variable pointed to by
that second argument. It returns the number.
You then continue to loop through the string until you reach another
digit, after which you can call strtol again!
In general, it is better to write your own code to parse input strings,
rather than use scanf.
I note that you are using memset in your code to zero your buffer
before reading input into it. The code will work equally well without
it, but I don't know the true context this code is used in, so perhaps
it is valid.
Also, you are putting an artificial 10-character limit on the user's
input. If the user wants to define a range between two five digit
numbers, it will not fit, and the end of the second number will be
chopped off. I usually use a function I have written to read the entire
line into dynamically allocated memory, which can be extended as
needed, but increasing the buffer size to 256 would do as well in this
case.
The function I have written to read lines from standard input can be
downloaded at http://www.nic-nac-project.de/~baseb...de/readline.c;
feel free to use it in your code.
I hope all this helps!
Jimmy Hartzell

 
Reply With Quote
 
 
 
 
Vladimir S. Oka
Guest
Posts: n/a
 
      03-04-2006
broeisi wrote:
> What advantages does sscanf offer over scanf?


It does not create potential buffer overflow vulnerability when used
with %s.

> I had the following code:
>
> #include <stdio.h>
> #include <string.h>
>
> int main(void)
> {
> int start, finish, values;
> char line[10];
>
> memset(line,0, 10);


Not really necessary...

>
> printf("Event numbers ? ");


Not terminating printf() with \n may result in no output until an \n is
emitted, or fflush(stdout) is executed.

> fgets(line, sizeof(line), stdin);
> values = sscanf(line,"%d %d", &start, &finish);
>
> printf("start = %d en finish = %d values = %d\n",
> start, finish, values);
>
> return 0;
> }
>
> but if tha user inputted for example : erte 5 6 ..the output of start
> and finished would not be 5 or 6 but some strange value...
>
> I thought that sscanf would find values that are integers and assign
> those integer values to the variables?


No, sscanf() will try to get it's values as specified and will
terminated as soon as it gets them, or as soon as it fails. In your
example above, it fails immediately (for "erte") and `start` and
`finish` remain uninitialised (you'd have been better initialising them
than the string). You should have checked `value` for errors, and you'd
have discovered this.

> If not how can I accomplish this?


If you want to get the first two valid integers out of anything user
might decide to input, you'd have to process it yourself. AFAIK,
there's no C function that'll do it for you.

PS
Please ignore post by `(E-Mail Removed)` as it has more than it's
fair share of inaccuracies.

--
BR, Vladimir

Avoid the Gates of Hell. Use Linux
(Unknown source)

 
Reply With Quote
 
Flashes of Sky
Guest
Posts: n/a
 
      03-04-2006
Re: comp.lang.c

> What advantages does sscanf offer over scanf?
>
> I had the following code:
>
> #include <stdio.h>
> #include <string.h>
>
> int main(void)
> {
> int start, finish, values;
> char line[10];
>
> memset(line,0, 10);
>
> printf("Event numbers ? ");
>
>
> fgets(line, sizeof(line), stdin);
> values = sscanf(line,"%d %d", &start, &finish);
>
> printf("start = %d en finish = %d values = %d\n",
> start, finish, values);
>
> return 0;
> }
>
> but if tha user inputted for example : erte 5 6 ..the output of start
> and finished would not be 5 or 6 but some strange value...
>
> I thought that sscanf would find values that are integers and assign
> those integer values to the variables?
>
> If not how can I accomplish this?
>


If possible on your system, use getline(), even if extensions are not
usually reccomended. Imposing arbitary limits on a program is not a
good habit to get into.

Here lies the problem:

values = sscanf(line,"%d %d", &start, &finish);

The problem with your slice of code is that you are assigning the
return value of the statement as well as expecting two decimals with a
space between them.:

The should-work way should be:

int start, finish, values;
char line[10];

memset(line,0, 10);

printf("Event numbers ? ");

fgets (line, sizeof(line), stdin);
sscanf (line, "%d","%d", &start, &finish);
sscanf (line, "%d %d", &value);

Hopw that helps and has no compile problems.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-04-2006
"Vladimir S. Oka" <(E-Mail Removed)> writes:
> broeisi wrote:
>> What advantages does sscanf offer over scanf?

>
> It does not create potential buffer overflow vulnerability when used
> with %s.

[...]

It does, but the vulnerability is easily controlled for sscanf()
(since you can know the size of the input string), but not easily
controlled for scanf() (since the program generally can't control how
long an input line might be).

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-04-2006
"broeisi" <(E-Mail Removed)> writes:
> What advantages does sscanf offer over scanf?

[snip]

By using fgets() and sscanf(), you divide the task into two parts:
getting the input line and extracting information from it.

scanf() consumes a variable number of characters from stdin, depending
on the format string and what's actually in the input line. It
commonly leaves a newline character on stdin, to be consumed by the
next input routine you call (which may not be able to handle it
properly). If you're trying to read, say, 3 input fields, and the
input only has 2 valid fields, scanf() will consume those two fields
and may leave you in the middle of the line.

In some cases, scanf() skips whitespace, *including* new-line
characters. If the user doesn't provide all the required fields on a
line, it keeps reading lines until you get all of them (or an error);
that's probably not what you want.

By contrast, fgets() consumes an entire line, including the trailing
newline. (That's not *quite* true; it only reads up to the maximum
number of characters you specify. You can either discard the rest of
the line after fgets(), or you can use a routine like the non-standard
but freely available ggets() that reads the entire line.) Once you
have the line in memory, you can use sscanf() to extract the required
information from it. sscanf(), like scanf(), returns the number of
items successfully translated. If that's less than the number you
asked for, you can reject the entire input line. If your program is
interactive, you can then prompt the user to try again.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Vladimir S. Oka
Guest
Posts: n/a
 
      03-04-2006
Keith Thompson wrote:

> "Vladimir S. Oka" <(E-Mail Removed)> writes:
>> broeisi wrote:
>>> What advantages does sscanf offer over scanf?

>>
>> It does not create potential buffer overflow vulnerability when used
>> with %s.

> [...]
>
> It does, but the vulnerability is easily controlled for sscanf()
> (since you can know the size of the input string), but not easily
> controlled for scanf() (since the program generally can't control how
> long an input line might be).


Yes, but that's self-inflicted (i.e. bad programming by choice).

--
BR, Vladimir

His heart was yours from the first moment that you met.

 
Reply With Quote
 
Chad
Guest
Posts: n/a
 
      03-04-2006
Vladimir S. Oka wrote:
> broeisi wrote:
> > What advantages does sscanf offer over scanf?

>
> It does not create potential buffer overflow vulnerability when used
> with %s.
>
> > I had the following code:
> >
> > #include <stdio.h>
> > #include <string.h>
> >
> > int main(void)
> > {
> > int start, finish, values;
> > char line[10];
> >
> > memset(line,0, 10);

>
> Not really necessary...
>
> >
> > printf("Event numbers ? ");

>
> Not terminating printf() with \n may result in no output until an \n is
> emitted, or fflush(stdout) is executed.
>


How could omitting '\n' possibly result with no output until an '\n' or
fllush is executed? Care to give some kind of example?

Thanks,
Chad

 
Reply With Quote
 
Chad
Guest
Posts: n/a
 
      03-04-2006
I meant *or fflush()*.

 
Reply With Quote
 
Vladimir S. Oka
Guest
Posts: n/a
 
      03-05-2006
Chad wrote:
> Vladimir S. Oka wrote:
>> broeisi wrote:
>> >
>> > printf("Event numbers ? ");

>>
>> Not terminating printf() with \n may result in no output until an \n
>> is emitted, or fflush(stdout) is executed.

>
> How could omitting '\n' possibly result with no output until an '\n'
> or fllush is executed? Care to give some kind of example?


No need for an example. Have a look at the Standard.

--
BR, Vladimir

My theology, briefly, is that the universe was dictated but not signed.
-- Christopher Morley

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Urgent positions: Sr Programmer Analyst (SPA) and Programmer Analyst(PRA)-06+month's- Carson City, NV. Isaac Java 0 12-08-2010 06:32 PM
Urgent positions: Sr Programmer Analyst (SPA) and Programmer Analyst(PRA)-06+month's- Carson City, NV. Isaac Java 0 12-08-2010 05:34 PM
Who gets higher salary a Java Programmer or a C++ Programmer? Sanny Java 391 01-06-2010 02:48 AM
Who gets higher salary a Java Programmer or a C++ Programmer? Sanny C++ 396 12-17-2008 06:13 PM
Question on sscanf Dan Smith C Programming 3 08-14-2003 12:42 AM



Advertisments