problem with functions

S

strictly_mk

Hi all, forgive me if there is a simple solution for this. I am going
through the following piece of code which simply calculates factorials
out of a book, but when i run it I get the answer 0 for whatever number
I input. Can anyone help?

Thanks in advance
strictly_mk

#include "stdio.h"

unsigned long long int return_factorial(unsigned int num); //function
prototype

int main (void) {

char input[3]; //keyboard input
int number; // number to work with

//prompt user

printf("Enter a positive integer for which the factorial will be
calculated: ");

fgets (input, sizeof(input), stdin); // read the input

sscanf (input, "%d", &number);

//check the input as conditional

if (number > 0) {

printf ("The factorial of %d is %lu.\n", number,
return_factorial(number));
} else {
printf ("You must enter a positive integer!\n");
}

getchar(); //pause and wait for user

return 0;
}

//This function takes a number and returns its factorial

unsigned long long int return_factorial(unsigned int num) {

unsigned long long int sum = 1;

unsigned int i; //multiplier to be used in calculating factorial

//Loop through every multiplier up to and including sum

for (sum = 1, i = 1; i <= num; ++i) {

sum *= i;
}

return sum;

} // End of return_factorial function
 
W

Walter Roberson

Hi all, forgive me if there is a simple solution for this. I am going
through the following piece of code which simply calculates factorials
out of a book, but when i run it I get the answer 0 for whatever number
I input.
unsigned long long int return_factorial(unsigned int num);
printf ("The factorial of %d is %lu.\n", number,
return_factorial(number));

return_factorial returns an unsigned long long, which you then
attempt to print using a format specifier suitable for an
unsigned long. Try using a format specifier of %llu
 
J

jacob navia

(e-mail address removed) a écrit :
Hi all, forgive me if there is a simple solution for this. I am going
through the following piece of code which simply calculates factorials
out of a book, but when i run it I get the answer 0 for whatever number
I input. Can anyone help?

Thanks in advance
strictly_mk

#include "stdio.h"

unsigned long long int return_factorial(unsigned int num); //function
prototype

int main (void) {

char input[3]; //keyboard input
int number; // number to work with

//prompt user

printf("Enter a positive integer for which the factorial will be
calculated: ");

fgets (input, sizeof(input), stdin); // read the input

sscanf (input, "%d", &number);

//check the input as conditional

if (number > 0) {

printf ("The factorial of %d is %lu.\n", number,
return_factorial(number));
} else {
printf ("You must enter a positive integer!\n");
}

getchar(); //pause and wait for user

return 0;
}

//This function takes a number and returns its factorial

unsigned long long int return_factorial(unsigned int num) {

unsigned long long int sum = 1;

unsigned int i; //multiplier to be used in calculating factorial

//Loop through every multiplier up to and including sum

for (sum = 1, i = 1; i <= num; ++i) {

sum *= i;
}

return sum;

} // End of return_factorial function

If I compile your code with lcc-win32 it will say:

Warning tprintfw.c: 23 printf argument mismatch for format u. Expected
int got unsigned long long

use %llu
 
E

Eric Sosman

jacob navia wrote On 05/24/06 14:03,:
(e-mail address removed) a écrit :
unsigned long long int return_factorial(unsigned int num); //function
prototype

int main (void) {
[...]

printf ("The factorial of %d is %lu.\n", number,
[...]

If I compile your code with lcc-win32 it will say:

Warning tprintfw.c: 23 printf argument mismatch for format u. Expected
int got unsigned long long

That diagnostic seems very confusing to me. Yes, there
is a mismatch between the format and the argument -- but the
message describes a mismatch that isn't there ...
 
F

Flash Gordon

jacob said:
(e-mail address removed) a écrit :
unsigned long long int return_factorial(unsigned int num);
//function
prototype

int main (void) {

char input[3]; //keyboard input
int number; // number to work with
printf ("The factorial of %d is %lu.\n", number,
return_factorial(number));

If I compile your code with lcc-win32 it will say:

Warning tprintfw.c: 23 printf argument mismatch for format u. Expected
int got unsigned long long

use %llu

Then you have a rather misleading warning. I see no u format and even if
I did it would expect an unsigned int, not a plain int. I do see an lu
format, but that expects an unsigned long not an int.
 
J

jacob navia

Eric Sosman a écrit :
jacob navia wrote On 05/24/06 14:03,:
(e-mail address removed) a écrit :
unsigned long long int return_factorial(unsigned int num); //function
prototype

int main (void) {
[...]

printf ("The factorial of %d is %lu.\n", number,
[...]

If I compile your code with lcc-win32 it will say:

Warning tprintfw.c: 23 printf argument mismatch for format u. Expected
int got unsigned long long


That diagnostic seems very confusing to me. Yes, there
is a mismatch between the format and the argument -- but the
message describes a mismatch that isn't there ...

I ignore the difference of long/int. If I would not do that, I would
warn when
printf("%lu",3);

Obviously in principle you are right, but in practice I try to emit less
warnings so that when there is a warning it doesn't get drowned
in the noise.

Basically when sizeof(effective type) != sizeof(expected type)
there is a warning
 
J

jacob navia

I ignore the difference of long/int. If I would not do that, I would
warn when
printf("%lu",3);

Obviously in principle you are right, but in practice I try to emit less
warnings so that when there is a warning it doesn't get drowned
in the noise.

Basically when sizeof(effective type) != sizeof(expected type)
there is a warning
 
K

Keith Thompson

jacob navia said:
I ignore the difference of long/int. If I would not do that, I would
warn when
printf("%lu",3);

Which you should.
Obviously in principle you are right, but in practice I try to emit less
warnings so that when there is a warning it doesn't get drowned
in the noise.

Basically when sizeof(effective type) != sizeof(expected type)
there is a warning

Thus you encourage non-portable code.
 
C

Clever Monkey

jacob said:
Eric Sosman a écrit :
jacob navia wrote On 05/24/06 14:03,:
(e-mail address removed) a écrit :

unsigned long long int return_factorial(unsigned int num);
//function
prototype

int main (void) {
[...]

printf ("The factorial of %d is %lu.\n", number,
[...]

If I compile your code with lcc-win32 it will say:

Warning tprintfw.c: 23 printf argument mismatch for format u.
Expected int got unsigned long long


That diagnostic seems very confusing to me. Yes, there
is a mismatch between the format and the argument -- but the
message describes a mismatch that isn't there ...

I ignore the difference of long/int. If I would not do that, I would
warn when
printf("%lu",3);

Obviously in principle you are right, but in practice I try to emit less
warnings so that when there is a warning it doesn't get drowned
in the noise.

Basically when sizeof(effective type) != sizeof(expected type)
there is a warning
If it is not a standard constraint, I guess there is no one saying you
should do any different, but you might consider levels of warning
controlled by switches.
 
J

jacob navia

Keith Thompson a écrit :
Which you should.

Well then, there would be so many such warnings that they would have
no longer any importance and the really important ones would get lost.

This is a matter of opinion of course. There is no requirement at all
for the compiler to emit a warning here, and the original poster's
compiler did not emit any, what led to the problem.
Thus you encourage non-portable code.

I do not encourage "non portable code", I just do not want to bother my
users you see?
But maybe I should have a level of warning that would apply here. I have
warning levels but did not use it in this situation.
 
K

Keith Thompson

jacob navia said:
Keith Thompson a écrit :

Well then, there would be so many such warnings that they would have
no longer any importance and the really important ones would get lost.

This is a matter of opinion of course. There is no requirement at all
for the compiler to emit a warning here, and the original poster's
compiler did not emit any, what led to the problem.

No, a warning isn't required, but issuing a warning for some format
string mismatches but not for this one is misleading.

printf("%lu", 3) invokes undefined behavior. It may happen to work in
your implementation. It's still undefined behavior, and you'd be
doing your users a favor by pointing it out.

[...]
I do not encourage "non portable code", I just do not want to bother my
users you see?

You don't want to bother your users by telling them their code is
non-portable.
 
E

Eric Sosman

jacob said:
I ignore the difference of long/int. If I would not do that, I would
warn when
printf("%lu",3);

Obviously in principle you are right, but in practice I try to emit less
warnings so that when there is a warning it doesn't get drowned
in the noise.

Basically when sizeof(effective type) != sizeof(expected type)
there is a warning

So, no warning for

printf ("%d = %s\n", "The Answer", 42);

.... on machines where sizeof(char*)==sizeof(int), right? Ugh.
One wonders whether half a seat belt is better or worse than
no seat belt at all.

gcc does a *much* better job of this; you may want to
study how it's done.
 
J

jacob navia

Eric Sosman a écrit :
So, no warning for

printf ("%d = %s\n", "The Answer", 42);

... on machines where sizeof(char*)==sizeof(int), right? Ugh.
One wonders whether half a seat belt is better or worse than
no seat belt at all.

gcc does a *much* better job of this; you may want to
study how it's done.

I was speaking about %d, %u. In this case we have:

D:\lcc\mc63\test>type twp.c
#include <stdio.h>
int main(void)
{
printf ("%d = %s\n", "The Answer", 42);
}

D:\lcc\mc63\test>lcc twp.c
Warning twp.c: 4 printf argument mismatch for format s. Expected char
pointer got int
0 errors, 1 warning

D:\lcc\mc63\test>

Note that printing a pointer with %d is still allowed. %s needs a char
pointer however, it is not symmetric.
 
K

Keith Thompson

jacob navia said:
I was speaking about %d, %u. In this case we have:

D:\lcc\mc63\test>type twp.c
#include <stdio.h>
int main(void)
{
printf ("%d = %s\n", "The Answer", 42);
}

D:\lcc\mc63\test>lcc twp.c
Warning twp.c: 4 printf argument mismatch for format s. Expected char
pointer got int
0 errors, 1 warning

D:\lcc\mc63\test>

Note that printing a pointer with %d is still allowed. %s needs a char
pointer however, it is not symmetric.

So you don't issue a warning for an attempt to print a pointer with "%d"?

Printing a pointer with "%d" may happen to work on your particular
implementation, but it's wrong. That's what "%p" is for.

gcc gets this right. lcc-win32 should do so as well.
 
R

Richard Heathfield

jacob navia said:
Keith Thompson a écrit :

Well then, there would be so many such warnings that they would have
no longer any importance and the really important ones would get lost.

Not true. I use gcc, which produces a diagnostic message for a mismatch
between printf format specifier and argument type, and yet there are not
"many such warnings" when I use it to compile my code, and so the really
important messages do not in fact get lost, despite your claim to the
contrary.
This is a matter of opinion of course. There is no requirement at all
for the compiler to emit a warning here,

That is unfortunately true, yes. I consider it a quality of implementation
issue. Good compilers give good diagnostics.
 
J

jacob navia

Richard Heathfield a écrit :
Not true. I use gcc, which produces a diagnostic message for a mismatch
between printf format specifier and argument type, and yet there are not
"many such warnings" when I use it to compile my code, and so the really
important messages do not in fact get lost, despite your claim to the
contrary.

Genius programmers like you should not use lcc-win32.
 
J

jacob navia

Keith Thompson a écrit :
So you don't issue a warning for an attempt to print a pointer with "%d"?

Printing a pointer with "%d" may happen to work on your particular
implementation, but it's wrong. That's what "%p" is for.

gcc gets this right. lcc-win32 should do so as well.

OK OK you are right. I have added warnings for mismatch with long/int,
and with mismatches pointer/int. This will appear only if you increase
the warning level or if you ask for the "code check" option in the IDE
 
R

Richard Heathfield

jacob navia said:
Richard Heathfield a écrit :

Genius programmers like you should not use lcc-win32.

It's kind of you to think of me as a genius programmer, but I'm afraid I
can't agree with you. I'm merely a careful programmer.

But you seem to be claiming that lcc-win32 is not for bright people. There,
I find it impossible to disagree.
 
F

Flash Gordon

jacob said:
Richard Heathfield a écrit :

Genius programmers like you should not use lcc-win32.

The better the programmer the less important the quality of the warning
since they are less likely to make the mistake and more likely to be ale
to work out why there was a diagnostic. So it is actually
inexperienced/poor programmers who should avoid lcc-win32.

As has been stated, the warning is a QOI issue, it is just that
lcc-win32 is showing a low quality of implementation here.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top