PDA

View Full Version : Nube Programmer Needs Proofreader




stephanos180
Sep 9, 2008, 08:27 AM
Hi, I've been working my way through "The C Programming Language" for about two days now, and am experimenting with some of the examples. Anyway, I'm at a point with what I call my 'Temperature Converter' where the app runs fine, except for the bolded part down below. You see, after I've entered '1' for Singly, and '1' or '2' for the next step, I input an integer, hit return, and have to do it once more to get a result. I don't understand why it's doing this. Please help, if you've got a moment; I can't figure it out.

#include<stdio.h>

int main()
{
int choice;

printf("\n\nWelcome to the Temperature Converter\n");
printf("\nWould you like to convert singly or incrementally?\n");
printf("1. Singly\t2. Incrementally ");
scanf("%d", &choice);

if (choice == 1) {
int choicetwo;

printf("\nIn which direction would you like to convert?\n");
printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius ");
scanf("%d", &choicetwo);

if (choicetwo == 1) {
int fahrenheit, celsius;

printf("\nPlease enter a starting value: ");
scanf("%d\n", &celsius);
fahrenheit = ((celsius * 9) / 5) + 32;
printf("Your corresponding fahrenheit value: %d", fahrenheit);
getchar();
getchar();
printf("\n");
return 0;
}

else if (choicetwo == 2) {
int fahrenheit, celsius;
printf("\nPlease enter a starting value: ");
scanf("%d\n", &fahrenheit);
celsius = 5 * (fahrenheit - 32) / 9;
printf("Your corresponding celsius value: %d", celsius);
getchar();
getchar();
printf("\n");
return 0;
}

}

else if (choice == 2) {
int fahrenheit, celsius;
int lower, upper, step;

printf("\nPlease enter a lower limit: ");
scanf("%d", &lower);
printf("Please enter an upper limit: ");
scanf("%d", &upper);
printf("Please enter a step size: ");
scanf("%d", &step);

while (fahrenheit <= upper) {
celsius = 5 * (fahrenheit - 32) / 9;
printf("%d\t%d\n", fahrenheit, celsius);
fahrenheit = fahrenheit + step;
}

getchar();
getchar();
printf("\n");
return 0;
}

}



toddburch
Sep 9, 2008, 09:11 AM
When you use scanf() as you are, the newline character is still sitting in the input buffer. You'll need to clear that newline character out of the input buffer. It would be more appropriate to clear it out just as soon as you issue the scanf() until some random time later on in the program.

Here's some code I wrote not too long ago that show one technique for clearing out the buffer - there are several other techniques.

(Just pay attention to the scanf() code - the other stuff might be more advanced code that you haven't experienced yet)


#include <stdio.h>

#define STORE_NAME "Sierra Sporting Goods"

void add_report() {
printf("Report added\n") ;
return ;
}

void report() {
printf("Report run\n") ;
return ;
}

void delete_record() {
printf("record deleted\n") ;
return ;
}

void change_record() {
printf("record changed\n") ;
return ;
}

int scanf_ok(int chars_read, int max, int * choice ) {
if (chars_read == EOF || chars_read == 0 ) return 0 ;
if (*choice < 1 || *choice > max) return 0 ;
return 1 ;
}


int main(void) {
int response = 0;
int chars_read ;
int i ;
struct {
const char *text ;
void (*function)() ;
} item[] = {

{ "Add a Report" ,add_report } ,
{ "Report" ,report } ,
{ "Delete a record",delete_record } ,
{ "Change a record",change_record } ,
{ "Quit" ,0 }

} ;

while ( 1 ) {

// Present the menu of options.
printf("\t%s\n\n", STORE_NAME) ;
for (i = 0 ; i < ( sizeof(item) / sizeof(*item)) ; i++) {
printf("%d = %s\n", i+1, item[i].text ) ;
}

// Read the response and validate it and process it
if ( scanf_ok( scanf("%d", &response), sizeof(item) / sizeof(*item) , &response ) ) {
if (item[response-1].function == 0) break ;
else item[response-1].function() ;
}
// else, tell user to try again.
else {
printf("Invalid or Non numeric value entered. Try again.\n") ;
while ( ( chars_read=getchar() ) != '\n' && chars_read != EOF) ; /* clear buffer */
}

} // while 1
return 0;
}

lee1210
Sep 9, 2008, 09:23 AM
Please use code tags. they look like this:
[ CODE][ /CODE]
without the spaces.

Here's what I came up with:

#include<stdio.h>

int main(int argc, char *argv[]) {
int choice;

printf("\n\nWelcome to the Temperature Converter\n");
printf("\nWould you like to convert singly or incrementally?\n");
printf("1. Singly\t2. Incrementally ");
scanf("%d", &choice);

if (choice == 1) {
int choicetwo;

printf("\nIn which direction would you like to convert?\n");
printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius ");
scanf("%d", &choicetwo);

if (choicetwo == 1) {
int fahrenheit, celsius;

printf("\nPlease enter a starting value: ");
scanf("%d", &celsius);
fahrenheit = ((celsius * 9) / 5) + 32;
printf("Your corresponding fahrenheit value: %d", fahrenheit);
fflush(stdout);
getchar();
printf("\n");
} else if (choicetwo == 2) {
int fahrenheit, celsius;
printf("\nPlease enter a starting value: ");
scanf("%d", &fahrenheit);
celsius = 5 * (fahrenheit - 32) / 9;
printf("Your corresponding celsius value: %d", celsius);
fflush(stdout);
getchar();
printf("\n");
}

} else if (choice == 2) {
int fahrenheit, celsius;
int lower, upper, step;

printf("\nPlease enter a lower limit: ");
scanf("%d", &lower);
printf("Please enter an upper limit: ");
scanf("%d", &upper);
printf("Please enter a step size: ");
scanf("%d", &step);
fahrenheit=lower;
while (fahrenheit <= upper) {
celsius = 5 * (fahrenheit - 32) / 9;
printf("%d\t%d\n", fahrenheit, celsius);
fahrenheit = fahrenheit + step;
}

fflush(stdout);
getchar();
printf("\n");
}
return 0;
}


In your scanf you were looking for a signed integer, then a newline. If you just look for a signed integer, once you have entered one, plus a newline, scanf should return. toddburch also demonstrated a method to clear the buffer completely, but this may or may not be necessary at this point. I could have sworn originally you were also asking about the return type of main. Most compilers will default the return value of a function to int implicitly if you don't specify. int is the correct return type of main, and it's probably best to just declare it as such explicitly.

-Lee

davethewave
Sep 9, 2008, 09:34 AM
why you're using the getchar()? I dropped it out!
try this (sorry, i don't have c compiler here, so this is no bullet proof code, but you can have some suggestion)
bye
DV


#include<stdio.h>

int CelsToFahr(int celsius){
int result = ((celsius * 9) / 5) + 32;
// this result will be rounded!
return result;
}

int FahrToCels(int fahr){
int result = 5 * (fahr - 32) / 9;
// this result will be rounded!
return result;
}

int main()
{
int choice = 0;
printf("\n\nWelcome to the Temperature Converter\n");
do // repeat the program
{
printf("\nWould you like to convert singly or incrementally?\n");
printf("1. Singly\t2. Incrementally\t3. Exit ");
scanf("%d", &choice);

// one time declaration
int fahreneit = 0, celsius = 0;

if (choice == 1) {
int choicetwo = 0;

printf("\nIn which direction would you like to convert?\n");
printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius");
scanf("%d", &choicetwo);

if (choicetwo == 1) {
printf("\nPlease enter a Celsius starting value: ");
scanf("%d\n", &celsius);
fahreneit = CelsToFahr(celsius);
printf("Your corresponding fahrenheit value: %d\n", fahrenheit);
}

else if (choicetwo == 2) {
printf("\nPlease enter a Fahrenheit starting value: ");
scanf("%d\n", &fahrenheit);
celsius = FahrToCels(fahreneit);
printf("Your corresponding celsius value: %d\n", celsius);
}
else {
printf("Wrong choice: %d",choichetwo);
}
}
else if (choice == 2)
{
int lower, upper, step;

printf("\nPlease enter a lower limit: ");
scanf("%d", &lower);
printf("Please enter an upper limit: ");
scanf("%d", &upper);
printf("Please enter a step size: ");
scanf("%d", &step);

while (fahrenheit <= upper)
{
celsius = FahrToCels(fahreneit);
printf("%d\t%d\n", fahrenheit, celsius);
fahrenheit = fahrenheit + step;
}
printf("\n");
}
else {
printf("Wrong choice:\t%d\d",choichetwo);
}
//program will stop only if we insert choiche number 3!
} while (choice != 3);

printf("\nProgram will now exit");
return 0;
}

toddburch
Sep 9, 2008, 10:02 AM
Please use code tags. they look like this:
[ CODE][ /CODE]
without the spaces.



Hey Lee, when demonstrating how to use code tags, you can use the [noparse] tag and it's closing tag with the slash to wrap the code tags. Therefore, you can say "please use the and tags".
:)

(I wasn't sure how to code an ending noparse tag, as that would have turned parsing back on, and defeated my effects...)

lee1210
Sep 9, 2008, 10:50 AM
Hey Lee, when demonstrating how to use code tags, you can use the [noparse] tag and it's closing tag with the slash to wrap the code tags. Therefore, you can say "please use the and tags".
:)

(I wasn't sure how to code an ending noparse tag, as that would have turned parsing back on, and defeated my effects...)

Ah, sweet. Is noparse even in the editing palette? If not, how did you divine this functionality?

-Lee

toddburch
Sep 9, 2008, 11:11 AM
Ah, sweet. Is noparse even in the editing palette? If not, how did you divine this functionality?

-Lee

It's a vBulletin thing. Lots of boards use the same software.

stephanos180
Sep 13, 2008, 08:58 AM
Please use code tags. they look like this:
[ CODE][ /CODE]
without the spaces.

Here's what I came up with:

#include<stdio.h>

int main(int argc, char *argv[]) {
int choice;

printf("\n\nWelcome to the Temperature Converter\n");
printf("\nWould you like to convert singly or incrementally?\n");
printf("1. Singly\t2. Incrementally ");
scanf("%d", &choice);

if (choice == 1) {
int choicetwo;

printf("\nIn which direction would you like to convert?\n");
printf("1. Celsius => Fahrenheit\t2. Fahrenheit => Celsius ");
scanf("%d", &choicetwo);

if (choicetwo == 1) {
int fahrenheit, celsius;

printf("\nPlease enter a starting value: ");
scanf("%d", &celsius);
fahrenheit = ((celsius * 9) / 5) + 32;
printf("Your corresponding fahrenheit value: %d", fahrenheit);
fflush(stdout);
getchar();
printf("\n");
} else if (choicetwo == 2) {
int fahrenheit, celsius;
printf("\nPlease enter a starting value: ");
scanf("%d", &fahrenheit);
celsius = 5 * (fahrenheit - 32) / 9;
printf("Your corresponding celsius value: %d", celsius);
fflush(stdout);
getchar();
printf("\n");
}

} else if (choice == 2) {
int fahrenheit, celsius;
int lower, upper, step;

printf("\nPlease enter a lower limit: ");
scanf("%d", &lower);
printf("Please enter an upper limit: ");
scanf("%d", &upper);
printf("Please enter a step size: ");
scanf("%d", &step);
fahrenheit=lower;
while (fahrenheit <= upper) {
celsius = 5 * (fahrenheit - 32) / 9;
printf("%d\t%d\n", fahrenheit, celsius);
fahrenheit = fahrenheit + step;
}

fflush(stdout);
getchar();
printf("\n");
}
return 0;
}


In your scanf you were looking for a signed integer, then a newline. If you just look for a signed integer, once you have entered one, plus a newline, scanf should return. toddburch also demonstrated a method to clear the buffer completely, but this may or may not be necessary at this point. I could have sworn originally you were also asking about the return type of main. Most compilers will default the return value of a function to int implicitly if you don't specify. int is the correct return type of main, and it's probably best to just declare it as such explicitly.

-Lee

Okay, what you did definitely works, but I don't understand what the meaning of what comes after main is. Could you explain? Also, what do you mean by saying that I was looking for a signed integer and a newline? What is fflush? Thanks a lot for your help, by the way.

lee1210
Sep 13, 2008, 09:24 AM
Okay, what you did definitely works, but I don't understand what the meaning of what comes after main is. Could you explain? Also, what do you mean by saying that I was looking for a signed integer and a newline? What is fflush? Thanks a lot for your help, by the way.

int main(int argc, char *argv[])
Is the "standard" signature of the main function.

int main(void)
Is also valid if you have no parameters. I prefer the prior because even if it's just for debugging, you might want to pass in some arguments to alter behavior. It's not always required, but that's just what i "default" to for the signature of main. The first int argument is the count of the number of command line parameters that have been passed to the application, and the second char ** is an array of char *s containing each of the parameters' value.

From the scanf manpage:

All conversions are introduced by the % (percent sign) character
or %n$ sequence. In the latter case the next pointer will be the n th
argument after the format string. The format string may also contain
other characters. White space (such as blanks, tabs, or newlines) in the
format string match any amount of white space, including none, in the
input. Everything else matches only itself. Scanning stops when an
input character does not match such a format character. Scanning also
stops when an input conversion cannot be made (see below).


So:

scanf("%d\n", &fahrenheit);


Will match an integer, a newline, then stop when it gets another input character. It won't get another input character until you press return again, so that's why you were having to press return twice.

From the fflush man page:

The function fflush() forces a write of all buffered data for the given
output or update stream via the stream's underlying write function. The
open status of the stream is unaffected.

If the stream argument is NULL, fflush() flushes all open output streams.


Essentially this ensures that a stream doesn't have any buffered output left, so things appear when and in some cases in the order you intend.

-Lee

stephanos180
Sep 13, 2008, 02:51 PM
int main(int argc, char *argv[])
Is the "standard" signature of the main function.

int main(void)
Is also valid if you have no parameters. I prefer the prior because even if it's just for debugging, you might want to pass in some arguments to alter behavior. It's not always required, but that's just what i "default" to for the signature of main. The first int argument is the count of the number of command line parameters that have been passed to the application, and the second char ** is an array of char *s containing each of the parameters' value.

From the scanf manpage:


So:

scanf("%d\n", &fahrenheit);


Will match an integer, a newline, then stop when it gets another input character. It won't get another input character until you press return again, so that's why you were having to press return twice.

From the fflush man page:


Essentially this ensures that a stream doesn't have any buffered output left, so things appear when and in some cases in the order you intend.

-Lee

Hey, Lee. You've helped a lot; that all makes sense now. Thanks a million.