Jump to content



Photo

swich, no output


  • Please log in to reply
26 replies to this topic

#1 Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 29 September 2013 - 17:00

Hello everyone.  I'm attempting to write a program that prompts the user for a quantity of partID's and then use a switch (loop) to id the part's unitprice for x amount of parts.  then display the total for those parts.  What I'm trying to do right now is just get the switch (loop) to work.  I'm not exactly worried about the last part of the total right this second.  What I have is :

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

void main()
{
	int partID = 0;
	double unitprice = 0;
	int ch = 0;

	printf("Please enter partID\n");
	printf("Please enter q to quit\n");

	ch = getch();

	do{
			switch(partID)
		{
		case 1:
			unitprice = 1.30;
			break;
		case 2:
			unitprice = 0.99;
			break;
		case 3:
			unitprice = 2.50;
			break;
		case 4:
			unitprice = 1.42;
			break;
		case 5:
			unitprice = 1000000.00;
			break;
		default:
			printf("Part cannot be found\n");
		case 0:
			partID++;
			break;
			}
	}
				while (partID != 0);
			

}

this is what it's outputting : (see picture below)

  which is outputting nothing but the printf's .  it wont even access the loop, nor will it exit.  what am I don't wrong?

Attached Images

  • failed3-2.png



#2 Eric

Eric

    Neowinian Senior

  • Tech Issues Solved: 11
  • Joined: 02-August 06
  • Location: Greenville, SC

Posted 29 September 2013 - 18:48

You're never comparing "ch" to anything and only the default switch case has any output.

Get rid of the do...while loop and just use switch like so:
switch(ch)
{
	case 1:
		unitprice = 1.30;
		break;
	case 2:
		unitprice = 0.99;
		break;
	case 3:
		unitprice = 2.50;
		break;
	case 4:
		unitprice = 1.42;
		break;
	case 5:
		unitprice = 1000000.00;
		break;
	default:
		printf("Part cannot be found\n");
		break;
}
You can then use an if statement to test if unitPrice is > 0 and output it afterwards.

#3 +Majesticmerc

Majesticmerc

    Resident Idealist

  • Tech Issues Solved: 5
  • Joined: 24-August 05
  • Location: United Kingdom
  • OS: Arch Linux / Win 7
  • Phone: HTC One X

Posted 29 September 2013 - 19:05

As Greywolf said, you're not using the right value in the switch statement. You're doing your switch using the value inside "partID", but entering your input into "ch". So partID will always have a value of zero!

The reason your application is not exiting is because you're stuck in an infinite loop. Because partID is always zero, you follow the zero case, which increments partID by one ("partID++"). Then it breaks out of the case statement and because partID isn't zero (it's now 1 because of partID++), you meet the loop condition and it loops round again, this time executing case 1, which sets unitprice to 1.30. From then on, partID will only ever be "1", and you never break out of the loop. You're effectively stuck until the end of time (or you kill the program).

The reason you're not seeing any output is because you're not doing anything to show output. You're just setting a variable value. Like Greywolf said, you'll need a printf statement to show the value of unitprice!

Also, because you're using a loop, I presume you mean't to put the line "ch = getch();" inside the loop?

#4 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 29 September 2013 - 20:13

After much help from a friend we've run unto another roadblock.  Instead of returning the decimal points it is truncating it into a whole number answer, when it shouldn't.  This is what we have

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main()


{

int input = 0;

do{


int partID;

long double quantity = 0.0; // we want to get the quantity ordered and also we want to make sure to make it a double for multiplying because we want to multiply doubles by doubles
long double unitPrice = 0.0;// it is good practice to capitalize the first letter of next word

printf("Please enter partID: ");
scanf("%d", &partID);

printf("\n\nPlease enter quantity: ");
scanf("%d", &quantity);

switch(partID)
{

case 0:    
unitPrice = (1.30 * quantity); 
printf("Total: %d\n", unitPrice);
input++;
break;

case 1:
unitPrice = (0.99 * quantity); //  multiply the quantity times the price to get total
printf("%d of item %d at %d each = %d\n\n\n", quantity, partID, unitPrice);
printf("Total: %d\n", unitPrice);
input++;
break;

case 2:
unitPrice = (2.50 * quantity);
printf("%d of item %d at %d each = %d\n\n\n", quantity, partID, unitPrice);
printf("Total: %d\n", unitPrice);
input++;
break;

case 3:
unitPrice = (1.42 * quantity);
printf("%d of item %d at %d each = %d\n\n\n", quantity, partID, unitPrice);
printf("Total: %d\n", unitPrice);
input++;
break;

case 4:
unitPrice = (1000000.00 * quantity);
printf("%d of item %d at %d each = %d\n\n\n", quantity, partID, unitPrice);
printf("Total: %d\n", unitPrice);
input++;
break;

default:
printf("Part cannot be found\n");
input++;
break;

}
}while (input < 1); 

}// This whole thing keeps returning a whole number. I cannot seem to get it to return a decimal.

This is what it's doing:  (see attached) any ideas as to why?

Attached Images

  • failed3-2.png


#5 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 29 September 2013 - 21:53

You are telling printf() to interpret your floating point numbers (quantity and unitPrice) as integers, hence the loss of precision. According to the printf() documentation you should be using "%f" to interpret your floating point numbers instead of "%d". For example:

printf("%f of item %d at %f each = %f\n\n\n", quantity, partID, unitPrice, quantity*unitPrice);

If you want to limit the output of your floating point numbers to two decimal places - a common request - you can do so by specifying their precision for printf(). For example:

printf("%4.2f of item %d at %4.2f each = %4.2f\n\n\n", quantity, partID, unitPrice, quantity*unitPrice);


#6 +Majesticmerc

Majesticmerc

    Resident Idealist

  • Tech Issues Solved: 5
  • Joined: 24-August 05
  • Location: United Kingdom
  • OS: Arch Linux / Win 7
  • Phone: HTC One X

Posted 29 September 2013 - 21:55

You're using %d in your printf, which shows output as an integer value, you want to use %f, which displays as floating point output:
 
printf("%d of item %d at %f each = %f\n\n\n", quantity, partID, unitPrice);
//                        ^        ^
//                        See here (and here)
A full list of printf format specifiers can be found here: http://www.cplusplus.../cstdio/printf/

#7 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 30 September 2013 - 00:48

Okay so I use %.02f and that will give me the two places after the decimal?



#8 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 September 2013 - 01:30

Okay so I use %.02f and that will give me the two places after the decimal?

 

No. Read the printf() documentation Majesticmerc and I linked to. "%4.2f" will give you two places after the decimal, just like in my example above. To expand on this further, the "4" tells printf() to print at least 4 characters. For example, "3.14" is exactly four characters. The ".2" tells printf() to print the floating point number rounded to exactly two decimal places. Therefore by requiring at least four characters and exactly two digits after the decimal, you ensure that you will always have either a natural number or a zero before the decimal point. For example, ".14" is not possible; it would be printed as "0.14" instead. I hope my explanation makes sense to you.



#9 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 30 September 2013 - 19:38

No. Read the printf() documentation Majesticmerc and I linked to. "%4.2f" will give you two places after the decimal, just like in my example above. To expand on this further, the "4" tells printf() to print at least 4 characters. For example, "3.14" is exactly four characters. The ".2" tells printf() to print the floating point number rounded to exactly two decimal places. Therefore by requiring at least four characters and exactly two digits after the decimal, you ensure that you will always have either a natural number or a zero before the decimal point. For example, ".14" is not possible; it would be printed as "0.14" instead. I hope my explanation makes sense to you.

thank you for the explanation, that makes perfect sense to me now! However now I am having problems with the output once again.  instead of getting extremely large numbers (like I was getting for a while) now I am getting 0.00 instead.  Not sure if I did that on accident by changing from %d to %4.2f.  Here is what I have code wise ...it will not allow me to attach a picture though. 

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main()


{

int input = 0;

do{


int partID;

double quantity = 0.0; 
double unitPrice = 0.0;
printf("Please enter partID: ");
scanf("%d", &partID);

printf("\n\nPlease enter quantity: ");
scanf("%d", &quantity);

switch(partID)
{

case 0:   
unitPrice = (1.30 * quantity);
printf("%4.2f of item %d at %4.2f each = %4.2f\n\n\n", quantity, partID, unitPrice);
printf("Total: %d\n", unitPrice);
input++;
break;

case 1:
unitPrice = (0.99 * quantity); // we want to multiply the quantity times the price to get total
printf("%4.2f of item %d at %4.2f each = %4.2f\n\n\n", quantity, partID, unitPrice);
printf("Total: %f\n", unitPrice);
input++;
break;

case 2:
unitPrice = (2.50 * quantity);
printf("%4.2f of item %d at %4.2f each = %4.2f\n\n\n", quantity, partID, unitPrice);
printf("Total: %f\n", unitPrice);
input++;
break;

case 3:
unitPrice = (1.42 * quantity);
printf("%4.2f of item %d at %4.2f each = %4.2f\n\n\n", quantity, partID, unitPrice);
printf("Total: %f\n", unitPrice);
input++;
break;

case 4:
unitPrice = (1000000.00 * quantity);
printf("%4.2f of item %d at %4.2f each = %4.2f\n\n\n", quantity, partID, unitPrice);
printf("Total: %f\n", unitPrice);
input++;
break;

default:
printf("Part cannot be found\n");
input++;
break;

}
}while (input < 1); // set this way otherwise it's an infinite loop


}



#10 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 30 September 2013 - 21:50

You have several problems with this iteration of your code. I'm actually a little surprised it doesn't seg. fault all the time. (It only seg. faults about 1 in every 5 times I run it.) The printf() statements in your switch case have four conversions specified but you only pass three variables to them. That means printf() is reading garbage data for the fourth conversion, which could result in either unspecified behavior or a seg. fault. One possible solution is to set unitPrice to the actual price per unit and calculate the total in your printf() statement.

unitPrice = 1.42;
printf("%4.2f of item %d at %4.2f each = %4.2f\n", quantity, partID, unitPrice, unitPrice * quantity);

Another problem is your scanf() of quantity. You are telling scanf() to interpret quantity as an integer while the variable itself is declared as a floating point. Because data storage is handled much differently for those variable types, the data your user enters for the quantity is not the same as the value stored in your variable. To correct this problem you either need to make quantity an int or scanf() "%f" instead of "%d". Based on your use of quantity I think the first solution is the better choice.

int quantity;

scanf("%d", &quantity);

Additionally, you could make your program more succinct by removing your do {} while() loop and placing the identical printf() statements outside of your switch case.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
    unsigned int partID;
    unsigned int quantity;
    
    double unitPrice;
    double total;
    
    enter_part_id:
    printf("Please enter partID: ");
    scanf("%u", &partID);
    
    printf("Please enter quantity: ");
    scanf("%u", &quantity);
    
    switch(partID)
    {
        case 0:   
            unitPrice = 1.30;
            break;
        case 1:
            unitPrice = 0.99;
            break;
        case 2:
            unitPrice = 2.50;
            break;
        case 3:
            unitPrice = 1.42;
            break;
        case 4:
            unitPrice = 1000000.00;
            break;
        default:
            printf("Part cannot be found\n");
            goto enter_part_id;
    }
    
    total = unitPrice * quantity;
    
    printf("%u of item %u at %4.2f each = %4.2f\n", quantity, partID, unitPrice, total);
    
    return 0;
}


#11 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 01 October 2013 - 04:05

Orangekillerx,

 

is there a way to do that but without the array caller?  I haven't used them yet and we aren't supposed to...but I was just curious if there was another way.  I thank you for all of your help!  You have no idea how frustrated I was getting with this issue. 



#12 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 01 October 2013 - 04:35

is there a way to do that but without the array caller?  I haven't used them yet and we aren't supposed to...but I was just curious if there was another way.  I thank you for all of your help!  You have no idea how frustrated I was getting with this issue. 

 

Array caller? I'm assuming you mean the goto statement. Some programmers believe that goto is nothing but trouble and should not be used under any circumstances. Obviously I'm not of that persuasion, but I do believe there are very few instances where goto is the proper construct to use. I only used it in this case because it made the logic simpler. You could easily accomplish the same thing using a loop, but using unitPrice as your sentinel (since it is being set anyway) rather than another variable like you had before.

 

My intention was to give you an example, not for you to use my code verbatim. That said, you have been very good about asking intelligent questions and showing real effort to understand C, so I will give you the modifications you requested in good faith.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[])
{
    unsigned int partID;
    unsigned int quantity;
    
    double unitPrice = 0.0;
    double total;
    
    /* Floating point numbers in C are not precise. You will encounter "odd"
     * bugs by attempting to compare a floating point number directly. For
     * example, if you set unitPrice = 1.30 then ask if(unitPrice == 1.30) the
     * comparison will most likely fail. unitPrice will be very close to 1.30,
     * just not exactly. Learn this lesson early and it will save you a lot of
     * grief later.
     */
    while(unitPrice < 1.0)
    {
        printf("Please enter partID: ");
        scanf("%u", &partID);
        
        printf("Please enter quantity: ");
        scanf("%u", &quantity);
        
        switch(partID)
        {
            case 0:   
                unitPrice = 1.30;
                break;
            case 1:
                unitPrice = 0.99;
                break;
            case 2:
                unitPrice = 2.50;
                break;
            case 3:
                unitPrice = 1.42;
                break;
            case 4:
                unitPrice = 1000000.00;
                break;
            default:
                printf("Part cannot be found\n");
                break;
        }
    }
    
    total = unitPrice * quantity;
    
    printf("%u of item %u at %4.2f each = %4.2f\n", quantity, partID, unitPrice, total);
    
    return 0;
}


#13 OP Terabojin

Terabojin

    Neowinian

  • Joined: 16-September 13
  • Location: California

Posted 01 October 2013 - 05:00

actually i was referring to that and int main(int argc, char * argv[]) because from what i read that calls an array in main.  maybe what i read was wrong, but that goto statement has me pausing. 



#14 +Karl L.

Karl L.

    xorangekiller

  • Tech Issues Solved: 15
  • Joined: 24-January 09
  • Location: Virginia, USA
  • OS: Debian Testing

Posted 01 October 2013 - 05:14

Actually no, the way I declared main() is proper syntax according the C standard; anything else is a non-standard deviation. The two parameters are related to the command-line arguments passed to your program, and the operating system collects that information whether you declare them in your C code or not. argv is a two-dimensional array (technically a pointer to that array, but that detail is a subtlety of C that you don't need to worry about right now) containing the arguments as they were passed to your program. argc tells you how many arguments there are.

 

For example, the following program takes several command line arguments. It uses a for loop to read each element of the array (which each correspond to a single argument passed to the program) and sets flags (bitwise) to indicate their presence. It then uses a series of if statements to check these flags and act on them. This program is a trivial example, but I think it succinctly demonstrates a very common real-world use of the parameters taken by main().

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

/* Startup flags */
#define SF_NONE     0  /* No flags are present */
#define SF_COUNT    1  /* Count to 100 */
#define SF_QUIET    2  /* Be less verbose than normal */
#define SF_HELP     4  /* Display our help information */
#define SF_ERROR    8  /* Get us out of here, Mr. Scott! */

int main(int argc, char * argv[])
{
    unsigned int flags = SF_NONE;
    
    for(int i = 1; i < argc; i++)
    {
        switch(argv[i][0])
        {
            case '-':
                switch( argv[i][1] )
                {
                    case '-':
                        if(strcmp("--count", argv[i]) == 0) flags |= SF_COUNT;
                        else if(strcmp("--quiet", argv[i]) == 0) flags |= SF_QUIET;
                        else if(strcmp("--help", argv[i]) == 0) flags |= SF_HELP;
                        else flags |= SF_ERROR;
                        break;
                    case 'c':
                        flags |= SF_COUNT;
                        break;
                    case 'q':
                        flags |= SF_QUIET;
                        break;
                    default:
                        flags |= SF_ERROR;
                        break;
                }
                break;
            default:
                flags |= SF_ERROR;
                break;
        }
        
        if(flags & SF_ERROR) break;
    }
    
    if(flags & SF_ERROR)
    {
        fprintf(stderr, "invalid syntax\n");
        fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
        return 1;
    }
    
    if(flags & SF_HELP)
    {
        printf("Usage: %s [OPTION]\n\n", argv[0]);
        printf("Process arguments and do something with them.\n\n");
        printf("  -c, --count              count from 1 to 100\n");
        printf("  -q, --quiet              be less verbose than normal\n");
        printf("      --help               display this help information\n\n");
    }
    
    if(flags & SF_COUNT)
    {
        if(!(flags & SF_QUIET)) printf("Counting from 1 to 100 ...\n");
        for(int i = 1; i <= 100; i++) if(!(flags & SF_QUIET)) printf("%d ", i);
        if(!(flags & SF_QUIET)) printf("\n");
    }
    
    if(flags == SF_NONE)
    {
        printf("no flags\n");
    }
    
    return 0;
}

Examples of the output of this program when invoked with various arguments are below.

$ ./argtest 
no flags
$ ./argtest -h
invalid syntax
Try './argtest --help' for more information.
$ ./argtest --help
Usage: ./argtest [OPTION]

Process arguments and do something with them.

  -c, --count              count from 1 to 100
  -q, --quiet              be less verbose than normal
      --help               display this help information

$ ./argtest --count
Counting from 1 to 100 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 
$ ./argtest --count --quiet
$ ./argtest -c
Counting from 1 to 100 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 
$ ./argtest -c -q


#15 Andre S.

Andre S.

    Asik

  • Tech Issues Solved: 6
  • Joined: 26-October 05

Posted 01 October 2013 - 20:32

actually i was referring to that and int main(int argc, char * argv[]) because from what i read that calls an array in main.  maybe what i read was wrong, but that goto statement has me pausing. 

If I may add to what xorangekiller said, the return type of main is int. void is accepted by Visual C++ but it's incorrect; it will not compile on other compilers. Stick to int main().

 

The "int argc, char** argv" part is the program arguments. If you're not interested in the program arguments, you can omit them and just write int main() or int main(void). This has no effect on the execution of the program. It does not "call an array" (which is nonsensical - only functions can be called, arrays are just data).





Click here to login or here to register to remove this ad, it's free!