I am learning C: a little problem with a simple source code

J

jacob navia

Le 01/11/11 21:21, Ben Bacarisse a écrit :
If it's the getch I remember, it can't fail -- by which I mean there is
no error return that can tell you anything.

<snip>

In a macintosh man getch gives

All routines return the integer ERR upon failure and an integer
value other than ERR (OK in the case of
ungetch()) upon successful completion.

POSIX specifies:

Upon successful completion getch(), mvgetch(), mvwgetch() and wgetch()
return the single-byte character, KEY_ value, or ERR. When in the
nodelay mode and no data is available, ERR is returned.

getch is not specified by ISO C
 
S

Seebs

Yes, of course........... int main() is more right but my choice is
such common that it is not more a error......

This is not how computers work. A common mistake is still a mistake.

This is like saying that, if enough people believe that gravity's
acceleration on the earth's surface is 9 meters/second/second, it's not
bad to use that number to design an airplane.

-s
 
J

Jens Thoms Toerring

zemir said:
Hi all and thanks for your suggestions, but i have solved. I think my
solution it is not good solution and more of you will be not very
happy but it seems to work fine, very fine. Please read:

Actually, there's notthing "solved".
#include <stdio.h>;
#include <math.h>;
const float Pi = 3.14159265358979323846;
float area(float r)
{
return(r*r*Pi);
}
float perimeter(float r) {
return(2*Pi*r);
}
void main() {

int main( void )
system("cls");
float r=0; int c;
printf("This programm calculate Area and Perimenter of a Circle");
printf("\n\nPlease insert radius value (in cm): ");

fflush( stdout );
scanf("%f", &r);
if( r > 0 ) {

If scanf() didn't find anything that looked like a number 'r' now has
some random value.
printf("Area is cm2: ");
printf("%.2f", area(r));
printf("\nPerimeter is cm: ");
printf("%.2f", perimeter(r));

You could do that all in a single line and you should have a '\n'
at the end.
} else {
printf("Value must to be a valid number\n");
printf("Press anykey to continue");

End that with a '\n'.
c=getch();
system("circle");

WTF is that supposed to do?
return 0;

So if the user entered a negative radius (or something not a number
and the value in 'r' was a negative number) you stop the program?
And the message to the user shoud be "Press any key to end the
program"...
}
printf("\nDo you want to continue? (y or elsewhere to exit)");

fflush( stdout );

Well, whatever the user enters, the program will stop. That's
nothing what your original program was supposed to do.
c=getch();
if(c==121) {

if ( c == 'y' )
system("circle");
return 0;
}

return 0;

All you did is write a program that behaves complete different.
That's not a solution in my books. A solution would be to cor-
rect the mistakes you had in the first version. I.e. check the
return value of scanf() and if it tells you that not as many
items could be read (in your case 1) as was expected clear the
input buffer by e.g. calling getc() until you find a '\n'. Then
you can call scanf() again without it trying to read the stuff
again it already rejected the last time round.

Regards, Jens
 
B

BartC

printf("\nDo you want to continue? (y or elsewhere to exit)");
c=getch();
if(c==121) {
system("circle");
return 0;
}
}

Then i have another question about variable c: the y value of int c, i
think, it is ascii code so it is the same in all the system?

Mostly. But it's still better to write:

if (c=='y') ...

then people can see what 121 was supposed to mean. And 'y' will work in
non-ascii systems too.
 
K

Keith Thompson

zemir said:
Ok, from now and in the future i will use always "int main()"
I am sure thai it is the right choice.

For C, "int main(void)" is correct. (For C++, it's "int main()".)
 
K

Kenny McCormack

For C, "int main(void)" is correct. (For C++, it's "int main()".)

As CLC returns to its roots...

(What about casting the return value of malloc()?)

--
"The anti-regulation business ethos is based on the charmingly naive notion
that people will not do unspeakable things for money." - Dana Carpender

Quoted by Paul Ciszek (pciszek at panix dot com). But what I want to know
is why is this diet/low-carb food author doing making pithy political/economic
statements?

Nevertheless, the above quote is dead-on, because, the thing is - business
in one breath tells us they don't need to be regulated (which is to say:
that they can morally self-regulate), then in the next breath tells us that
corporations are amoral entities which have no obligations to anyone except
their officers and shareholders, then in the next breath they tell us they
don't need to be regulated (that they can morally self-regulate) ...
 
N

Nick Keighley

[...] i am writing a
small programm to calculate the perimeter and the area of a circle;
this is:

#include <stdio.h>;
#include <math.h>;

there should not be a semi-colon (;) after a #include (or indeed any
pre-processor directive)
float area(float r)
{                                                   /*define area
function*/
        return(r*r*3.14);}

the layout is odd (maybe partly your browser) So I assuem you meant
somethign like this:-

float area(float r)
{
/*define area function*/
return(r*r*3.14);
}

a simple consistent layout i better. return is not a function so it
needs no brackets. And a bit of whitespace makes things easier to read

float area(float r)
{
/*define area function*/
return r * r * 3.14;
}
 
B

BartC

Kenny McCormack said:
As CLC returns to its roots...

zemir is right. All these mis-declarations of 'main' are so widespread,
wouldn't it have been easier to have accepted them into the standard, than
have to be point them out every time? Especially as the compilers used don't
seem to be complaining.
(What about casting the return value of malloc()?)

(That's also been mentioned so many times that I've no idea now whether you
are supposed to cast or not. (And no I'm not interested in knowing; the way
I do it seems to work so I don't care.))
 
J

James Kuyper

On 11/02/2011 07:04 AM, BartC wrote:
....
zemir is right. All these mis-declarations of 'main' are so widespread,
wouldn't it have been easier to have accepted them into the standard, than
have to be point them out every time? Especially as the compilers used don't
seem to be complaining.

I'm not happy with that idea, but I could live with it. However, in this
particular case his definition of the body of main() attempts to return
a value. Even if support for void main() were made mandatory, I think
that returning a value from main() when it has been declared as not
returning a value should still be a constraint violation.
 
J

James Kuyper

[...] i am writing a
small programm to calculate the perimeter and the area of a circle;
this is:

#include <stdio.h>;
#include <math.h>;

there should not be a semi-colon (;) after a #include (or indeed any
pre-processor directive)


Every preprocessor directive includes, as part of the directive, the
terminating new-line. Therefore, "a semi-colon (;) after a ...
preprocessor directive" would have to look like this:

#include <stdio.h>
;

I think what you mean is that they cannot have a ';' as the last
character before the terminating new-line.

Comments get removed during translation phase 3, while preprocessing
directives are not translated until phase 4, so

#include <stdio.h> //;

would also be legal. I assume that you meant a ';' that was not part of
a comment.

There are still four kinds of preprocessing directives which can have a
';' as the last character before the terminating new-line, even if it's
not part of a comment:

#define semicolon ;
#This qualifies as a pre-processing directive (6.10p3);
#error This is an error;
#pragma highlight red ;

However, those are the only four.
 
N

Nick Keighley

[...] i am writing a
small programm to calculate the perimeter and the area of a circle;
this is:
#include <stdio.h>;
#include <math.h>;
there should not be a semi-colon (;) after a #include (or indeed any
pre-processor directive)

Every preprocessor directive includes, as part of the directive, the
terminating new-line. Therefore, "a semi-colon (;) after a ...
preprocessor directive" would have to look like this:

        #include <stdio.h>
        ;

I think what you mean is that they cannot have a ';' as the last
character before the terminating new-line.

Comments get removed during translation phase 3, while preprocessing
directives are not translated until phase 4, so

        #include <stdio.h> //;

would also be legal. I assume that you meant a ';' that was not part of
a comment.

There are still four kinds of preprocessing directives which can have a
';' as the last character before the terminating new-line, even if it's
not part of a comment:

#define semicolon ;
#This qualifies as a pre-processing directive (6.10p3);
#error This is an error;
#pragma highlight red ;

However, those are the only four.

but not terribly helpful to the OP, I'd considered mentioning the
first one but didn't think it would add much to my post.
 
S

Seebs

zemir is right. All these mis-declarations of 'main' are so widespread,
wouldn't it have been easier to have accepted them into the standard, than
have to be point them out every time? Especially as the compilers used don't
seem to be complaining.

It might or might not have been easier, but it would have been a pretty
significant burden on some implementors, for no real benefit. At least
some compilers complain...

-s
 
K

Keith Thompson

BartC said:
zemir is right. All these mis-declarations of 'main' are so widespread,
wouldn't it have been easier to have accepted them into the standard, than
have to be point them out every time? Especially as the compilers used don't
seem to be complaining.

It would have been slightly easier for programmers (what's so
bloody hard about writing it correctly in the first place?),
slightly more difficult for most implementers, and potentially
substantially more difficult for some implementers. Consider a
system where functions returning void and functions returning int
use significantly different calling conventions. If compilers were
required to accept "void main(void)", they'd have to do some kind
of fixup to make it look like "int main(void)" to the linker.

My own preference would have been to make defining "main" incorrectly
a constraint violation, not undefined behavior. For example:

Permit "int main(void)", "int main()", or "int main(int
argc, char *argv[])", or equivalent (with "or equivalent"
being defined sufficiently clearly). In addition, permit any
implementation-defined form; if a compiler wants to support
"void main(void)", it can do so. A definition of "main" that
doesn't match either one of the three explicitly permitted
forms or a form defined by the implementation violates
a constraint, requiring a diagnostic. (N.B.: This is a
hypothetical suggestion, not a description of the language as
it's actually defined.)

(Aside: I've argued that "int main()" is not equivalent to "int
main(void)", which is why I list it separately.)

Programs using "void main(void)" (as well as books that claim it's
valid), would have been weeded out over the years as they failed
to compile.

If the committee had chosen to require "void main(void)" to be
accepted as well, it wouldn't particularly bother me. I've never
argued that there's anything *intrinsically* wrong with it, just
that the standard doesn't support it.

But the fact remains that the language is defined the way it is,
and conforming to that definition shouldn't be at all difficult.
Failing to do so can *sometimes* indicate a lack of attention to
detail that can and should reduce the reader's trust in the rest
of the code (Schildt's books are a classic example).

IMHO, the blame lies not with the authors of the Standard, but with
the authors of books and tutorials (most of whom had access to the
Standard and therefore should have known better) who decided, for
no apparent reason, to tell their readers that "void main(void)"
is perfectly valid.
(That's also been mentioned so many times that I've no idea now whether you
are supposed to cast or not. (And no I'm not interested in knowing; the way
I do it seems to work so I don't care.))

If you don't care, why mention it? And since the vast majority of the
posts discussing it have been consistent, how can you be unaware of the
answer?
 
S

Seebs

I've often wondered where the habit originated. In the original K&R
they just use "main()", which given the old default function return is
int rule was fair enough. So where did "void main()" originate?

No clue. It was popularized by Schildt, so far as I can tell, but I have
never seen an actual origin identified. Probably DOS or Windows users,
I'd guess?

-s
 
I

Ian Collins

zemir is right. All these mis-declarations of 'main' are so widespread,
wouldn't it have been easier to have accepted them into the standard, than
have to be point them out every time? Especially as the compilers used don't
seem to be complaining.

I've often wondered where the habit originated. In the original K&R
they just use "main()", which given the old default function return is
int rule was fair enough. So where did "void main()" originate?
 
D

Dann Corbit

Hi all and thanks for your suggestions, but i have solved. I think my
solution it is not good solution and more of you will be not very
happy but it seems to work fine, very fine. Please read:

#include <stdio.h>;
#include <math.h>;
const float Pi = 3.14159265358979323846;
float area(float r)
{ /*define area
function*/
return(r*r*Pi);
}
float perimeter(float r) { /
*define perimeter function*/
return(2*Pi*r);
}
void main() {
system("cls");
float r=0; int c;/*define radius and c variable used to control the
behaviour of program*/
printf("This programm calculate Area and Perimenter of a Circle");
printf("\n\nPlease insert radius value (in cm): "); /*input of the
radius value*/
scanf("%f", &r);
if(r>0) {
printf("Area is cm2: ");
printf("%.2f", area(r)); /*call area
function*/
printf("\nPerimeter is cm: ");
printf("%.2f", perimeter(r)); /*call perimeter
function*/
} else {
printf("Value must to be a valid number\n");
printf("Press anykey to continue");
c=getch();
system("circle");
return 0;
}
printf("\nDo you want to continue? (y or elsewhere to exit)");
c=getch();
if(c==121) {
system("circle");
return 0;
}
}

Then i have another question about variable c: the y value of int c, i
think, it is ascii code so it is the same in all the system?

On EBCDIC systems y is 169. Consider also that they might type in a
capital 'Y' and get surprised if it gets interpreted as quitting time.
You've got some non-portable stuff in your code but then again, I used a
goto so both of us are evil and doomed forever more.

I came up with this variant when I saw your original post.

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

static const double pi_approximation =
3.1415926535897932384626433832795028841971693993751;
static char string[32767];

/* Area of a circle with radius r */
double area (double r)
{
return (r * r * pi_approximation);
}

/* Perimeter of a circle with radius r */
double perimeter (double r)
{
return (2.0 * pi_approximation * r);
}

/* Safely collect a string (due to Jack Klein) */
char * getsafe (char *buffer, int count)
{
char *result = buffer, *np;
if ((buffer == NULL) || (count < 1))
result = NULL;
else if (count == 1)
*result = '\0';
else if ((result = fgets (buffer, count, stdin)) != NULL)
if (np = strchr (buffer, '\n'))
*np = '\0';
return result;
}


int main (void)
{
double r = 0;
int c = 0;
int converted;
printf ("This programm calculate Area and Perimenter of a Circle");
do
{
doofus:
printf ("\n\nPlease give radius value (in cm):");
fflush (stdout);
getsafe (string, sizeof string);
r = atof (string);
if (r <= 0)
{
if (r == 0 && string[0] == '0')
{
puts ("Both perimeter and radius are zero, but you knew
that.");
}
else
{
puts ("No such thing as a negative radius in Euclidean
geometry.");
goto doofus;
}
}
printf ("Area = %.2f cm^2\n", area (r));
printf ("Perimeter = %.2f cm\n", perimeter (r));
puts ("Do you want to continue? (y or elsewhere to exit):");
fflush (stdout);
c = getchar ();
}
while (toupper (c) == 'Y');
return 0;
}
 
K

Kaz Kylheku

I've often wondered where the habit originated. In the original K&R
they just use "main()", which given the old default function return is

The original K&R did not have a void keyword. That came from C++.
So did prototypes.

C++ was a better C already, so C played catchup.

When C++ void and prototypes were introduced, programmers working
with updated compilers were able to change functions of the form

procedure()
int x;
{
}

into:

void procedure(int x)
{
}
int rule was fair enough. So where did "void main()" originate?

Probably from mindlessly appying the above pattern to update programs
to the newer language.

Gee, main is not declared to return a value, and just falls off the end.
Insert some voids and it's ANSI C!

Then, of course, some book authors (e.g. H. Schildt) also presented the
practice as correct, as far back as the 1980's.
 
I

Ike Naar

int main (void)
{
double r = 0;

pointless initialization.
int c = 0;
int converted;

unused variable.
printf ("This programm calculate Area and Perimenter of a Circle");
do
{
doofus:
printf ("\n\nPlease give radius value (in cm):");
fflush (stdout);
getsafe (string, sizeof string);
r = atof (string);

#include said:
if (r <= 0)
{
if (r == 0 && string[0] == '0')

This test will fail for e.g. the input string ".0".
 
B

Bill Reid

This is not how computers work.  A common mistake is still a mistake.
Oh great, somebody who knows how computers work, I've been looking
for somebody like that to explain something...
This is like saying that, if enough people believe that gravity's
acceleration on the earth's surface is 9 meters/second/second, it's not
bad to use that number to design an airplane.
Oh yes, people could die...soooooooo, please explain how a
common OS, such as say, Windows(TM), uses the return value
from main()? Or for that matter, a TRUE Unix(TM)? Or any
other OSs that you are an expert on?

And while you're on the subject, how should a computer
expert such as yourself set the return value of main() to be
correct?
Can you define what conditions would cause me to set it one
way or another? Of course, I'm assuming that since the
ANSI C committee decreed that main() have a specific set
of return values, every computer in the world conforms
to those values and does something useful with them, so
I would have perfect "portability" between platforms
for my "correct" C code, and nobody would die as a result
of my using an incorrect return value...

Also, what's "winmain()"? I've seen that a lot, returns
something called a "Windows handle", what's up with that?

You know, I've asked these questions here before, but
never received an answer, but I'm sure that's because
there wasn't a computer expert such as yourself to answer
them...

P.S. Note carefully that I didn't ask if it was OK
to return a value from main() (or any function) when
the function prototype does not have a return value,
and I always use the correct prototype for main(),
just because it's annoying to have the error messages
from the compiler, just like this topic is annoying...
 
M

Malcolm McLean

Oh yes, people could die...soooooooo, please explain how a
common OS, such as say, Windows(TM), uses the return value
from main()?  Or for that matter, a TRUE Unix(TM)?  Or any
other OSs that you are an expert on?
You return 0 to indicate that the program exited normally, and
EXIT_FAILURE to indicate that it encountered some sort of error
condition.

Many OSes allow scripts or other programs to use these values, to
indicate whether a program did what was intended or not.
 

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

Forum statistics

Threads
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top