473,246 Members | 1,947 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,246 software developers and data experts.

what does strod return??

Hi,
I have problem with the following function - it was intended to ask a
user for a 4-digits number:

double ask_for_number (void)
{
char *notint;
char s2[3];
double entered_number;

do
{
printf("\tplease enter 4-digits number: ");
scanf("%s", s2);
if ( strlen (s2) !=4 )
printf ("Wrong input - input must consist of 4 integer
numbers.\n");
else
entered_numberr = strtod(s2, &notint);
}
while (*notint);
printf ("you entered: %d", entered_number); /* ???? */
return entered_number;
};

My question is: why in the line /* ???? */ we got something else that
input number? I'd like to use entered_number in the other piece of
program, so I have to be sure it works properly... I guess this is a
matter of a strod function - could you give me a clue how it works or
how to write some similar function without strod?
best regards,
a.

Jan 1 '06 #1
6 5729
"alternativa" <al***********@wp.pl> writes:
I have problem with the following function - it was intended to ask a
user for a 4-digits number:

double ask_for_number (void)
{
char *notint;
char s2[3];
double entered_number; [snip] printf ("you entered: %d", entered_number); /* ???? */
return entered_number;
};


"%d" expects an int. Passing a double invokes undefined behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <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.
Jan 1 '06 #2
On 31 Dec 2005 16:13:51 -0800, "alternativa" <al***********@wp.pl>
wrote in comp.lang.c:
Hi,
I have problem with the following function - it was intended to ask a
user for a 4-digits number:

double ask_for_number (void)
{
char *notint;
char s2[3];
This is not a large enough array to hold four digits of input. It has
three elements, s2[0], s2[1], and s2[2]. It can either hold three
arbitrary character values -- not a string -- or a string consisting
of two characters, with the '\0' that terminates the string being in
the third and final char.
double entered_number;

do
{
printf("\tplease enter 4-digits number: ");
scanf("%s", s2);
Using the scanf "%s" conversion specifier without a length parameter
is just plain suicidal. scanf() will attempt to pull characters from
the standard input stream and store them in successive memory
locations, then store a terminating '\0' at the end. If the input
contains four characters, the first three will wind up in your array,
then scanf() will try to write the fourth character and the
terminating '\0' into memory that does not belong to you, past the end
of the array. This is undefined behavior.

And what do you think happens if the user types forty or fifty
characters?
if ( strlen (s2) !=4 )
Now you are asking the strlen() function to access memory past the end
of your array.
printf ("Wrong input - input must consist of 4 integer
numbers.\n");
else
entered_numberr = strtod(s2, &notint);
}
while (*notint);
printf ("you entered: %d", entered_number); /* ???? */
return entered_number;
};

My question is: why in the line /* ???? */ we got something else that
input number? I'd like to use entered_number in the other piece of
program, so I have to be sure it works properly... I guess this is a
matter of a strod function - could you give me a clue how it works or
how to write some similar function without strod?
best regards,
a.


There is no requirement that anything at all be output by that line.
In fact, there is no requirement that the program even reach that
point. If the array overflows, there is undefined behavior and there
are no requirements at all any more, there is no right or wrong
behavior. But if there is no undefined behavior, strlen() on the
input array will return either 0, 1, or 2, so your program will never
reach the line.

And, as Keith pointed out, your are passing a double to printf() with
a "%d" conversion specifier, which is for int values. You need to use
"%f" to output a double.

But the bigger problem is your use of an array that's too small, your
program logic insisting that the input is not valid unless it
overflows the array, and using scanf("%n") without a length modifier.

To fix your program, you need to change the definition of s2 from [3]
to [5] elements. Then you need to use "%4s", as a conversion
specifier to scanf() so it will accept only four characters, and still
have room for the '\0'.

And finally you need to use "%f" in place of "%d" as the conversion
specifier to printf().

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jan 1 '06 #3
alternativa a écrit :
Hi,
I have problem with the following function - it was intended to ask a
user for a 4-digits number:
Do you mean 4-decimal-digit number ?
double ask_for_number (void)
{
char *notint;
char s2[3];
This is good for a 2 characters string. Sounds too short for a
"4-decimal-digit number", don't you think so ?
double entered_number;

do
{
printf("\tplease enter 4-digits number: ");
scanf("%s", s2);


Bad and dangerous use of scanf(). (No input limit, no return test, no
purge...) You should have used fgets() that is much more safer.

Try this, and ask for details if you don't understand.

static long ask_for_number (void)
{
long entered_number = 0;
int err = 1;

do
{
char s2[16];
printf("\tplease enter 4-decimal-digits number: ");
fflush (stdout);

fgets(s2, sizeof s2, stdin);

/* check the input */
{
char *p = strchr(s2, '\n');

if (p != NULL)
{
/* clean */
*p = 0;
}
else
{
/* purge */
int c;

while ((c = getchar()) != '\n' && c != EOF)
{
}
}
}

if (strlen (s2) != 4)
{
printf ("Wrong input - input must consist of 4 decimal digits
numbers.\n");
}
else
{
char *notint;
entered_number = strtol (s2, &notint, 10);

if (*notint != 0)
{
printf ("Wrong input - input must consist of 4 decimal
digits numbers.\n");
}
else
{
err = 0;
}
}
}
while (err);

return entered_number;
}
int main (void)
{
long n = ask_for_number ();

printf ("you entered: %ld\n", n);

return 0;
}
--
A+

Emmanuel Delahaye
Jan 1 '06 #4
thanks a lot, I'll work on it :)

Jan 1 '06 #5
Emmanuel Delahaye wrote:
alternativa a écrit :
Hi,
I have problem with the following function - it was intended to ask a
user for a 4-digits number:

Do you mean 4-decimal-digit number ?
double ask_for_number (void)
{
char *notint;
char s2[3];

This is good for a 2 characters string. Sounds too short for a
"4-decimal-digit number", don't you think so ?
double entered_number;

do
{
printf("\tplease enter 4-digits number: ");
scanf("%s", s2);

Bad and dangerous use of scanf(). (No input limit, no return test, no
purge...) You should have used fgets() that is much more safer.

Try this, and ask for details if you don't understand.

static long ask_for_number (void)
{
long entered_number = 0;
int err = 1;

do
{
char s2[16];
printf("\tplease enter 4-decimal-digits number: ");
fflush (stdout);

fgets(s2, sizeof s2, stdin);

/* check the input */
{
char *p = strchr(s2, '\n');

if (p != NULL)
{
/* clean */
*p = 0;
}
else
{
/* purge */
int c;

while ((c = getchar()) != '\n' && c != EOF)
{
}
}
}

if (strlen (s2) != 4)
{
printf ("Wrong input - input must consist of 4 decimal digits
numbers.\n");
}
else
{
char *notint;
entered_number = strtol (s2, &notint, 10);

if (*notint != 0)
{
printf ("Wrong input - input must consist of 4 decimal
digits numbers.\n");
}
else
{
err = 0;
}
}
}
while (err);

return entered_number;
}
int main (void)
{
long n = ask_for_number ();

printf ("you entered: %ld\n", n);

return 0;
}


But, if the user enters a line such as
xxx1
where x represents a space or tab character,
then your function will return the entered number
although it is not a 4-digit number. Of course, the
correction is trivial.
Jan 1 '06 #6
M. Nejat AYDIN a écrit :
But, if the user enters a line such as
xxx1
where x represents a space or tab character,
then your function will return the entered number
although it is not a 4-digit number. Of course, the
correction is trivial.


Good catch.

--
A+

Emmanuel Delahaye
Jan 2 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: antonyliu2002 | last post by:
I know it returns the string that fills the TextBox. What does it return when nothing is put into the TextBox? The empty string ""? Or Null? Or Nothing? I haven't been able to figure it out.
4
by: Vikas Rana | last post by:
Hi all, I am a bit confused about the method java.sql.DatabaseMetaData.nullsAreSortedHigh(). What exactly does this return? If this returns true, are nulls considered as the highest value? Or...
21
by: Niu Xiao | last post by:
I see a lot of use in function declarations, such as size_t fread(void* restrict ptr, size_t size, size_t nobj, FILE* restrict fp); but what does the keyword 'restrict' mean? there is no...
18
by: Seeker | last post by:
I essentially copied this program from K&R: #include <stdio.h> #include <stdlib.h> int main() { int c;
13
by: Protoman | last post by:
I'm getting an error: 10 C:\Dev-Cpp\Enigma.cpp no match for 'operator<' in 'i < (+cleartext)->std::basic_string<_CharT, _Traits, _Alloc>::end ()' Code: Enigma.hpp...
9
by: James Dow Allen | last post by:
How about this idea? Post fragments of C code which seem fun, interesting or instructive. Puzzles can be posed in various ways. (What does this do? Can you see the bug? How to code this for...
10
by: thomas | last post by:
Hi, It's known that strdup() returns a char* type, but sometimes the following code generates warning messages. char *x = ... char *p = strdup(x); You must change it to
3
guillermobytes
by: guillermobytes | last post by:
Hi, I was wondering what does PDO return when there are no records matching the query? i.e. i query for a column.name = 'John' and there is no 'John' in the table. thanks for your answer. ...
21
by: rahul sinha | last post by:
When you type one character and press enter, it prints two values, so it turns out that it does read "enter" from the input buffer. What does getchar actually return on reading enter? Moreover I...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.