PDA

View Full Version : What's wrong with this program?




hoangluong
Feb 20, 2009, 05:14 AM
Hi, I'm trying to figure out where it goes wrong, but I still can't. This program aims to find min and max values among the 4 integers entered by the user. This is a programming exercise from King's book. Could you please help? Thanks a lot!!!

// Programming Project 5.7
#include<stdio.h>

int main(void)
{
int a = 0, b = 0, c = 0, d = 0;
int max = 0, min = 0;

printf("Enter 4 integers: ");
scanf("%d%d%d%d", &a, &b, &c, &d);

if(a > b && b > c && c > d) {
max = a;
min = d;
}
else if (b > c && c > d && d > a) {
max = b;
min = a;
}
else if(c > d && d > a && a > b) {
max = c;
min = b;
}
else if(d > a && a > b && b > c) {
max = d;
min = c;
}

printf("Largest: %d\nSmallest: %d\n", max, min);
return 0;
}



eddietr
Feb 20, 2009, 05:25 AM
Would you mind putting the code in [code] tags so it's quicker to read? It would be much easier for someone to help then.

Cromulent
Feb 20, 2009, 05:27 AM
Logic error.

None of your four if / else / else if statements is always true.

You have four variables. There are far more than 4 possible combinations available. For instance what happens in your program if d is greater than c and a is greater than d?

Edit : Added a little.

robbieduncan
Feb 20, 2009, 05:37 AM
Also stylistically it's not good. Personally I'd define two functions called min and max that take two arguements and return the expected min or max of arguements. Then you can simply call max(max(a,b),max(c,d)) to find the max and similar for the min...

hoangluong
Feb 20, 2009, 05:42 AM
Also stylistically it's not good. Personally I'd define two functions called min and max that take two arguements and return the expected min or max of arguements. Then you can simply call max(max(a,b),max(c,d)) to find the max and similar for the min...

Thanks. II'm working on the "if statements" chapter, so I'm supposed to use only if statements to do it. The exercise gives a hint that 4 if statements would be sufficient. As a self-taught novice, I find constructing nested if statements rather confusing in some cases.

macsmurf
Feb 20, 2009, 08:33 AM
Thanks. II'm working on the "if statements" chapter, so I'm supposed to use only if statements to do it. The exercise gives a hint that 4 if statements would be sufficient. As a self-taught novice, I find constructing nested if statements rather confusing in some cases.

Well, I don't think that is a very good hint. It might be possible to do it with 4 but the somewhat straightforward solution is to do it with 5. I'm at a loss as to how one would do it with 4.

Hints: For two variables one if-else statement should suffice. For each additional variable, two if statements in the form of if (..) {...} else if (...) {...} should suffice.

EDIT: OK, so I did it with 4 if statements as well, so it seems possible, but it's more of a puzzle than anything else. I still say aim for 5 or more as long as it works. Then see if you can do it smarter.

macsmurf
Feb 22, 2009, 01:42 PM
Apparently the thread starter has gone, but in case anyone is interested, here is a way to do it with four if statements:


// Programming Project 5.7
#include<stdio.h>

int main(void) {
int a = 0, b = 0, c = 0, d = 0;
int min = 0, minab = 0, mincd = 0, max = 0, maxab = 0, maxcd = 0;

printf("Enter 4 integers: ");
scanf("%d%d%d%d", &a, &b, &c, &d);

if (b > a) {
minab = a;
maxab = b;
} else {
minab = b;
maxab = a;
}

if (c > d) {
mincd = d;
maxcd = c;
} else {
mincd = c;
maxcd = d;
}

if (maxab > maxcd) {
max = maxab;
} else {
max = maxcd;
}

if (minab < mincd) {
min = minab;
} else {
min = mincd;
}

printf("Largest: %d\nSmallest: %d\n", max, min);
return 0;
}

robbieduncan
Feb 22, 2009, 05:23 PM
Apparently the thread starter has gone, but in case anyone is interested, here is a way to do it with four if statements:

Very nice indeed. Although personally I'd prefer to use more if statements and fewer variables... but that's just a personal preference.

hoangluong
Feb 22, 2009, 07:09 PM
Hi Macsmurf, thanks a lot. I'm not gone. It's just because I'm trying to find time off my work and study for programming. I like to learn programming a lot but I just can't go to a programming class or so due to my work and non-IT majors at the uni. Could you or anyone help me with this program? It's from the King's book chapter on "Basic Types", i.e characters, integers, etc... I've written this program and it has bugs which I don't know where from. When I did the exercise converting from 24-hour format to 12-hour format, it was all OK. But when I'm doing the reverse it presents errors. Is the error due to not using getchar()? Thanks...

// Programming Project 7.9

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

int main(void)
{
int hour12 = 0, minute12 = 0;
char form1 = 0, form2 = 0;

printf("Enter a 12-hour time: ");
scanf("%d:%d%c", &hour12, &minute12, &form1, &form2);

printf("Equivalent 24-hour time: ");

form1 = toupper (form1);
form2 = toupper (form2);

if (form1 == 'A' && form2 == 'M') {
if (hour12 == 0) printf("00");
else if (hour12 == 1) printf("01");
else if (hour12 == 2) printf("02");
else if (hour12 == 3) printf("03");
else if (hour12 == 4) printf("04");
else if (hour12 == 5) printf("05");
else if (hour12 == 6) printf("06");
else if (hour12 == 7) printf("07");
else if (hour12 == 8) printf("08");
else if (hour12 == 9) printf("09");
else if (hour12 == 10) printf("10");
else if (hour12 == 11) printf("11");
else if (hour12 == 12) printf("12");

}

else if (form1 == 'P' && form2 == 'M') {
if (hour12 == 1) printf("13");
else if (hour12 == 2) printf("14");
else if (hour12 == 3) printf("15");
else if (hour12 == 4) printf("16");
else if (hour12 == 5) printf("17");
else if (hour12 == 6) printf("18");
else if (hour12 == 7) printf("19");
else if (hour12 == 8) printf("20");
else if (hour12 == 9) printf("21");
else if (hour12 == 10) printf("22");
else if (hour12 == 11) printf("23");
else if (hour12 == 12) printf("24");

}

printf(":%d", &minute12);

return 0;
}

eddietr
Feb 22, 2009, 07:35 PM
What is the error you are getting?

hoangluong
Feb 22, 2009, 07:51 PM
What is the error you are getting?

I compiled and ran it, but it gave unexpected results (wrong stuffs in bold) as below:

hoang-luong-luongs-macbook-pro:~ hoangluongluong$ cd King
hoang-luong-luongs-macbook-pro:King hoangluongluong$ gcc -o pp7_9 pp7_9.c
hoang-luong-luongs-macbook-pro:King hoangluongluong$ ./pp7_9
Enter a 12-hour time: 9:11PM
Equivalent 24-hour time: :-1073743560hoang-luong-luongs-macbook-pro:King hoangluongluong$

eddietr
Feb 22, 2009, 08:49 PM
I compiled and ran it, but it gave unexpected results (wrong stuffs in bold) as below:

OK, well I see two small mistakes in your code.

First in the scanf I believe you are missing one '%c'. It seems you want to get form1 and form2 as two characters.

And then also in this line:


printf(":%d", &minute12);


Here you are printing the memory address of 'minute12', when I think what you really want to print is the value of minute12.

Hope that helps.

hoangluong
Feb 22, 2009, 10:14 PM
OK, well I see two small mistakes in your code.

First in the scanf I believe you are missing one '%c'. It seems you want to get form1 and form2 as two characters.

And then also in this line:


printf(":%d", &minute12);


Here you are printing the memory address of 'minute12', when I think what you really want to print is the value of minute12.

Hope that helps.

Thanks a lot for your time! I made a very basic/stupid mistake. I've done many exercises from each of the chapters without committing this kind of mistakes, and then when I got stuck on this one I spent time thinking about the logic, etc... without being able to spot such a mistake. Thanks a lot.

Could you or anyone help me with the next one I just have tried.

// Programming Project 7.4

#include<stdio.h>

int main(void)
{
char number;

printf("Enter phone number: ");
scanf("%c", &number);

switch (number) {
case 'A': case 'B': case 'C':
printf("2"); break;
case 'D': case 'E': case 'F':
printf("3"); break;
case 'G': case 'H': case 'I':
printf("4"); break;
case 'J': case 'K': case 'L':
printf("5"); break;
case 'M': case 'N': case 'O':
printf("6"); break;
case 'P': case 'R': case 'S':
printf("7"); break;
case 'T': case 'U': case 'V':
printf("8"); break;
case 'W': case 'X': case 'Y':
printf("9"); break;
}

return 0;

}

The program is to translate an alphabetic phone number into numeric form (Programming Project 7.4 from King's book). Additional info: ABC = 2, DEF = 3, etc... When I entered ABC, for example, it gives just one 2, not three 2s and it guess this is where it's wrong. How do I fix this code?

lee1210
Feb 22, 2009, 10:35 PM
I would think that you'd want to read a character at a time in a loop, or a string once, then loop over the length of that string, decoding a character at a time. One way or the other, you are only reading one character, then decoding it presently, which isn't what you seem to be wanting to do.

-Lee

eddietr
Feb 22, 2009, 10:41 PM
Thanks a lot for your time! I made a very basic/stupid mistake. I've done many exercises from each of the chapters without committing this kind of mistakes, and then when I got stuck on this one I spent time thinking about the logic, etc... without being able to spot such a mistake. Thanks a lot.


Believe me, if you end up doing this for a living, you'll do this all the time. It's always good to have someone else look at it.

And it's also useful to step through something like this in the debugger. Then you'll see the value of a particular variable is nothing like you expected, and you'll figure out what's wrong.


When I entered ABC, for example, it gives just one 2, not three 2s and it guess this is where it's wrong. How do I fix this code?

Well, you are reading only one single character from the input.

macsmurf
Feb 23, 2009, 02:14 AM
Very nice indeed. Although personally I'd prefer to use more if statements and fewer variables... but that's just a personal preference.

Of course no one would do it like this in real life. :) In real life most people would probably just put the numbers into an array and sort it with whatever sorting algorithm is availiable through the standard library.

It's a good exercise, though.

WhiteRabbit
Feb 23, 2009, 02:31 AM
I think the min max problem could be solved more efficiently still.

int a, b, c, ...
int min, max
// get input: a, b, c, ... are set to various values
min = a;
max = a;
if (b < min) min = b;
if (b > max) max = b;
if (c < min) min = c;
if (c > max) max = c;
// ... keep testing all values
// at this point, min will be equal to the smallest, and max the largest


This may result in more condition evaluations (n -1) * 2 or six needed for four values, but it's much easier to read. If the values are stored in an array, this could be simplified even further using a for loop.

hoangluong
Feb 23, 2009, 03:19 AM
Hi, thank you all for helping me out. I just wrote this program that computes scrabble value of a word, e.g. 1 = AEILNORSTU, 2 = DG, etc... I can't figure out where it goes wrong. It sums up not according to the assignment of numeric values to letters as I did for the switch statement. E.g: When I typed in "pitfall", it should be 12 instead of 7 as I currently receive.

// Programming Project 7.5

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

int main (void)
{
char word;
int scrabble_value = 0;

printf("Enter a word: ");

while (word = getchar() != '\n') {
switch (tolower (word)) {
case 'd': case 'g': scrabble_value += 2; break;
case 'b': case 'c': case 'm': case 'p': scrabble_value += 3; break;
case 'f': case 'h': case 'v': case 'w': case 'y': scrabble_value += 4; break;
case 'k': scrabble_value += 5; break;
case 'j': case 'x': scrabble_value += 8; break;
case 'q': case 'z': scrabble_value += 10; break;
default: scrabble_value++; break;
}
}

printf ("Scrabble value: %d.\n", scrabble_value);

return 0;
}

hoangluong
Feb 23, 2009, 04:40 AM
I would think that you'd want to read a character at a time in a loop, or a string once, then loop over the length of that string, decoding a character at a time. One way or the other, you are only reading one character, then decoding it presently, which isn't what you seem to be wanting to do.

-Lee

Thanks a lot for your hint. After a while thinking over your hint, I now came up with this revised program, which seems to be working properly this time.

// Programming Project 7.4

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

int main(void)
{
char ch;

printf("Enter phone number: ");

while ((ch = getchar()) != '\n') {
switch (toupper (ch)) {
case 'A': case 'B': case 'C': printf("2"); break;
case 'D': case 'E': case 'F': printf("3"); break;
case 'G': case 'H': case 'I': printf("4"); break;
case 'J': case 'K': case 'L': printf("5"); break;
case 'M': case 'N': case 'O': printf("6"); break;
case 'P': case 'R': case 'S': printf("7"); break;
case 'T': case 'U': case 'V': printf("8"); break;
default: printf("9"); break;
}
}

printf("\n");

return 0;
}

lee1210
Feb 23, 2009, 08:30 AM
Hi, thank you all for helping me out. I just wrote this program that computes scrabble value of a word, e.g. 1 = AEILNORSTU, 2 = DG, etc... I can't figure out where it goes wrong. It sums up not according to the assignment of numeric values to letters as I did for the switch statement. E.g: When I typed in "pitfall", it should be 12 instead of 7 as I currently receive.

// Programming Project 7.5

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

int main (void)
{
char word;
int scrabble_value = 0;

printf("Enter a word: ");

while (word = getchar() != '\n') {
switch (tolower (word)) {
case 'd': case 'g': scrabble_value += 2; break;
case 'b': case 'c': case 'm': case 'p': scrabble_value += 3; break;
case 'f': case 'h': case 'v': case 'w': case 'y': scrabble_value += 4; break;
case 'k': scrabble_value += 5; break;
case 'j': case 'x': scrabble_value += 8; break;
case 'q': case 'z': scrabble_value += 10; break;
default: scrabble_value++; break;
}
}

printf ("Scrabble value: %d.\n", scrabble_value);

return 0;
}

!= has higher precedence than =. word = getchar() != '\n' is evaluated as if it were parenthesized as so:
word = (getchar() != '\n')

This leads to word either being equal to 1 or 0, and when it is equal to 0 the loop stops. You need to parenthesize the expression so the assignment to word is done first, then a comparison to 0 is made.

As a note, in this program and others you have posted, you've made the default in a switch handle all of the expected cases that you don't want to enumerate. Anything you are expecting should be enumerated, and default should handle the "unexpected" input. For example, the character '7' typed into your scrabble program will be valued with 1 point, since that is the default in your switch. Doing this would have also helped you catch this error, because you could display an error in the default: section of your switch, which would have been hit every time since word was 1 (not '1', but ascii 1).

-Lee

WhiteRabbit
Feb 23, 2009, 12:15 PM
Thanks a lot for your hint. After a while thinking over your hint, I now came up with this revised program, which seems to be working properly this time.

// Programming Project 7.4

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

int main(void)
{
char ch;

printf("Enter phone number: ");

while ((ch = getchar()) != '\n') {
switch (toupper (ch)) {
case 'A': case 'B': case 'C': printf("2"); break;
case 'D': case 'E': case 'F': printf("3"); break;
case 'G': case 'H': case 'I': printf("4"); break;
case 'J': case 'K': case 'L': printf("5"); break;
case 'M': case 'N': case 'O': printf("6"); break;
case 'P': case 'R': case 'S': printf("7"); break;
case 'T': case 'U': case 'V': printf("8"); break;
default: printf("9"); break;
}
}

printf("\n");

return 0;
}

It looks like you're missing 'Q' from evaluation. And the last characters should be evaluated, the default should be no conversion (spit back what the user typed)

Here is a more efficient way to do it

char phone [] = "1-800-GIVE-LIFE ABCDEFGHIJKLMNOPQRSTUVWXYZ\0";
for (int i = 0; phone [i]; i++) { // loop code for each char
// special cases
if (phone [i] == 'S') phone [i] = '7';
if (phone [i] == 'V') phone [i] = '8';
if (phone [i] == 'Y' || phone [i] = 'Z') phone [i] = '9';
// all other chars
if (phone [i] < 'A' || phone [i] > 'Z')
continue; // non alphabetical, skip
else
phone [i] = (phone [i] - 'A') / 3 + '2'; // note the alpha '2' not numeric 2
}
printf ("%s\n", phone);
// output should be: 1-800-4483-5433 22233344455566677778889999

hoangluong
Feb 23, 2009, 11:35 PM
Can you please give me a hint for writing this program? The program aims to prints a 1-month calendar. The user gives the number of days in the month and the day of the week on which the month starts. I'm stuck on the if statement that tests whether a day is the last day in a week so that I can put in a new-line character. What's more, I'm stuck on how to print, say, the 1st day of the month that falls on the starting day that the user enters.

// Programming Project 6.8
#include<stdio.h>

int main (void)
{
int nd = 0;
int sd = 0;

printf("Enter number of days in month: ");
scanf("%d", &nd);
printf("Enter starting day of the week (1=Sun, 7=Sat): ");
scanf("%d", &sd);

int i = 0;
for (i = 1; i <= nd; i++) {
if () {

}
printf("%5d", i);
}

printf("\n");

return 0;
}

macsmurf
Feb 24, 2009, 09:05 AM
Can you please give me a hint for writing this program? The program aims to prints a 1-month calendar. The user gives the number of days in the month and the day of the week on which the month starts. I'm stuck on the if statement that tests whether a day is the last day in a week so that I can put in a new-line character. What's more, I'm stuck on how to print, say, the 1st day of the month that falls on the starting day that the user enters.


Here's a hint: Check out the modulus operator.

WhiteRabbit
Feb 24, 2009, 02:06 PM
Yes, the mod % operator is quite useful for determining if something is a multiple of, oh I don't know, perhaps seven.

Also, the best way to separate the days is a tab (use \t inside a string). If the user indicates the month starts on Tuesday, the first thing to do is tab over twice.

hoangluong
Feb 24, 2009, 09:53 PM
Thank you all. I have revised the calendar printing program as follows. I've tried hard to understand what I could do based on your hint, but I just couldn't. Here is a program that I wrote my way, which is rather bad as the output doesn't come out nicely (and the output doesn't seem right???). Could you please suggest a better/neater way to do it?

// Programming Project 6.8
#include<stdio.h>

int main (void)
{
int nd = 0;
int sd = 0;

printf("Enter number of days in month: ");
scanf("%d", &nd);
printf("Enter starting day of the week (1=Sun, 7=Sat): ");
scanf("%d", &sd);

int i = 0;
for (i = 1; i < sd; i++) {
printf ("\t");
for (i = 1; i <= nd; i++) {
if (i == 8 - (8 % sd) || i == 15 - (8 % sd) || i == 22 - (8 % sd) || i == 29 - (8 % sd)) {
printf ("\n");
}
printf ("%5d", i);
}

}
printf ("\n\n");

return 0;
}





I'm feeling so disappointed with my ability. I've read the first 10 chapters from King's book and tried to do all of the chapter projects. I could do correctly as few as half of the chapter projects only. Learning C is the first programming experience of mine and I've been doing it on my own because I can't go to a formal class.

I've seen that so many guys of you have taught yourself at least one programming language and it seems that most of you all have later become a true programmer/expert. It's very possible that I was born to learn sth else and not programming. The more I learn, the more interested I am in programming, but it also seems that the more challenging I find learning programming by self-study. Does any one of you have a similar experience when you first tried to pick up a programming language? I'm feeling so frustrated that when I look at a chapter it seems that there are only a few basic principles, all seeming basic/understandable/not difficult to comprehend, but when it comes to doing problems/projects/exercises I always get stuck on applying principles/theory to problems. Most of the exercises that I've posted in here are said to be simple, not complicated, but I've been struggling to get them right. So disappointed with myself.

WhiteRabbit
Feb 25, 2009, 01:35 AM
Software development can be quite challenging. To solve a problem the programmer must break down the problem to the smallest factors possible. You really have to think like a machine.

I notice that you are using pretty much the shortest possible identifiers possible. Although there is less code, the code is not very readable. It's a tremendous help to anyone reading your code (including yourself, and however good a programmer you are, you will spend more time reading your code than writing) that you use meaningful variable and method names. Most IDEs will autocomplete identifiers for you, so don't be afraid of being to descriptive.

It seems as though you have the mod operator backwards. Just remember that mod is a division. Whatever it is you want to divide goes on the left, and what you want to divide by goes on the right. Mod returns the remainder of this division. 7%8=7, 8%7=1, 7%7=0.

Also, you have a nested for loop (for loop inside of a for loop). These can be very useful for iterating a grid with x and y for example (this calendar view does not need one). The problem with your nested loop is that you are using the same variable to iterate both loops. Although the syntax is legal, it's easy to setup some errors doing this. The for loop inside is changing the same variable that the outside loop is using. It's best to avoid having any code other than the for loop itself modify the iterator.


int daysInMonth = 30, firstDay = 3;
// display a header
printf (" S\t M\t T\t W\t T\t F\t S");
// insert some blank days
for (int i=1; i<firstDay; i++)
printf ("\t");
// iterate all the days of the month
for (int thisDay=1; thisDay<=daysInMonth; thisDay++) {
// display the day and follow it with a tab
printf ("%2d\t", thisDay);
// if this happens to be a Saturday (column is a multiple of 7
// we can find out the column by adding thisDay and firstDay
if ( (thisDay+firstDay-1) % 7 == 0) // firstDay is 1 to 7, so we must subtract 1
// then we'll need to break the line
printf ("\n");
}

macsmurf
Feb 25, 2009, 04:34 PM
I'm feeling so disappointed with my ability. I've read the first 10 chapters from King's book and tried to do all of the chapter projects. I could do correctly as few as half of the chapter projects only. Learning C is the first programming experience of mine and I've been doing it on my own because I can't go to a formal class.

I've seen that so many guys of you have taught yourself at least one programming language and it seems that most of you all have later become a true programmer/expert. It's very possible that I was born to learn sth else and not programming. The more I learn, the more interested I am in programming, but it also seems that the more challenging I find learning programming by self-study. Does any one of you have a similar experience when you first tried to pick up a programming language? I'm feeling so frustrated that when I look at a chapter it seems that there are only a few basic principles, all seeming basic/understandable/not difficult to comprehend, but when it comes to doing problems/projects/exercises I always get stuck on applying principles/theory to problems. Most of the exercises that I've posted in here are said to be simple, not complicated, but I've been struggling to get them right. So disappointed with myself.

OK, so first of all: Programming is hard! I tend to think of it in a way comparable to math. Most would agree that math is hard. The hardest part about math is applying principles to solve a problem. After a while you develop an intuition on how to solve certain kinds of problems, but the only way to develop that intuition is by working at it. Same thing with programming.

However, programming is also fun! Part of the fun is chipping away at a problem for hours on end until you get it right. If that is not your definition of fun you will find programming intensely frustrating. It's more of a mindset thing than anything else. Mind you, C is not exactly the best language to start out with as there are a lot of details you need to get right in order for your program to work properly. You might have a better time with something like java, although object oriented programming can be hard to get your head around, but at least you don't have to deal with pointers.

Anyway, if you keep at it, eventually it should get easier, but it takes a lot of work :)

eddietr
Feb 25, 2009, 04:58 PM
I'm feeling so disappointed with my ability. I've read the first 10 chapters from King's book and tried to do all of the chapter projects. I could do correctly as few as half of the chapter projects only. Learning C is the first programming experience of mine and I've been doing it on my own because I can't go to a formal class.

I wouldn't get so discouraged. You've been asking good questions (and hopefully getting decent answers :)) and you've really been moving at a pretty strong pace, it seems.

Maybe slow down a bit. And maybe just work on something fun, rather than another exercise.

It takes a while to get the hang of this stuff. But the good news is once you understand it, then picking up additional languages and new devices and new ideas and such will be quite easy and fun. Just hang in there and understand there is a lot of work in getting started.

Good luck and keep the questions coming. Hopefully people can continue to help.