C problem but no error when building?

Discussion in 'Mac Programming' started by larswik, Dec 7, 2010.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    Hey, I am learning about pointers in C and to further understand I wrote my own test code. What I am trying to do is have the console ask for a letter and then pass that argument to a function that evaluates it using a switch. When it finds the matching case an integer value is assigned to the local variable 'CritNum'. This value is then pointed back to Main to the integer variable named 'cNumber' (I hope I did not screw up my explanation terminology to much, i am learning).

    Anyway, I was surprised after writing it I got no errors on my first try!!! But that joy was short lived since the program stalls after asking the first question? I am thinking the code fails in my Function but I can't see where after looking at it for an hour. If it gave me errors I could try to fix it but nothing. Any help would be appreciated.

    Code:
    #include <stdio.h>
    
    void crit(char crit, int *cNumberPTR);
    
    int main (int argc, const char * argv[]) {
    	
    	char letter;
    	int cNumber;
    	
    	printf("Enter a letter from A-I:");
    	scanf("%c", letter);
    	
    	crit(letter, &cNumber);
    	
    	printf("The letter %c is the number is %d", letter,cNumber);
    
        return 0;
    }
    void crit(char crit, int *cNumberPTR) {
    	
    	int CritNum;
    	
    	switch (crit) {
    		case 'a':
    			CritNum = 10;
    		case 'A':
    			CritNum = 10;
    			break;
    		case 'b':
    			CritNum = 20;
    		case 'B':
    			CritNum = 20;
    			break;
    		case 'c':
    			CritNum = 30;
    			break;
    		case 'C':
    			CritNum = 30;
    		case 'd':
    			CritNum = 50;
    		case 'D':
    			CritNum = 50;
    			break;
    		case 'e':
    			CritNum = 70;
    		case 'E':
    			CritNum = 70;
    			break;
    		case 'f':
    			CritNum = 80;
    		case 'F':
    			CritNum = 80;
    			break;
    		case 'g':
    			CritNum = 90;
    		case 'G':
    			CritNum = 90;
    			break;
    		case 'h':
    			CritNum = 100;
    		case 'H':
    			CritNum = 100;
    			break;
    		case 'i':
    			CritNum = 120;
    		case 'I':
    			CritNum = 120;
    			break;
    		default:
    			CritNum = 0;
    			break;
    	}
    			
    			*cNumberPTR = CritNum;
    }
    
     
  2. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #2
    Code:
    gcc -o myprog test.c
    test.c: In function âmainâ:
    test.c:11: warning: format â%câ expects type âchar *â, but argument 2 has type âintâ
    
    Fix:

    Code:
            scanf("%c", [B]&[/B]letter);
    
    Result:

    Code:
    choas-computer-3:c choas$ gcc -o myprog test.c
    choas-computer-3:c choas$ ./myprog
    Enter a letter from A-I:D
    The letter D is the number is 50
    
     
  3. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #3
    OMG! Thank you!!! I can't believe I over looked that little tiny &. That kept me looking for hours and I was sure the problem was in the Function and it was not.

    Thank you very much chOas!

    -Lars
     
  4. ChOas macrumors regular

    Joined:
    Nov 24, 2006
    Location:
    The Netherlands
    #4
    No problem :)

    Strange that the warning wasn't displayed for you though.
     
  5. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #5
    It compiled and ran in the console. I wish it would have given me an error when I pressed build, I would have caught it then.

    Thanks again.

    -Lars
     
  6. RiskyMr macrumors newbie

    Joined:
    Apr 8, 2009
    #6
    You probably want a break statement in the 'C' case.
     
  7. lee1210, Dec 7, 2010
    Last edited: Dec 7, 2010

    lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    Just for kicks:
    Code:
    #include <stdio.h>
    
    void crit(char crit, int *cNumberPTR);
    
    int main (int argc, const char * argv[]) {
    	
    	char letter;
    	int cNumber;
    	
    	printf("Enter a letter from A-I:");
    	scanf("%c", &letter);
    	
    	crit(letter, &cNumber);
    	
    	printf("The letter %c is the number is %d\n", letter,cNumber);
    
        return 0;
    }
    
    void crit(char crit, int *cNumberPTR) {
    	int letterToNumberMap[] = {10,20,30,50,70,80,90,100,120};
    	int offset = 0;
    	*cNumberPTR = 0;
    	if(crit < 'A' || (crit > 'I' && crit < 'a') || crit > 'i') {
    		printf("Invalid crit character, %c, entered.\n",crit);
    		return;
    	}
    	if(crit >= 'a') {
    		offset = crit - 'a';
    	} else {
    		offset = crit - 'A';
    	}
    	*cNumberPTR = letterToNumberMap[offset];
    }
    
    If you're really wanting to reduce crit's length:
    Code:
    void crit(char crit, int *cNumberPTR) {
    	int letterToNumberMap[] = {10,20,30,50,70,80,90,100,120};
    	*cNumberPTR = 0;
    	if(crit < 'A' || (crit > 'I' && crit < 'a') || crit > 'i') return;
    	*cNumberPTR = crit >= 'a'?letterToNumberMap[crit-'a']:letterToNumberMap[crit-'A'];
    }
    
    -Lee

    Edit: While I'm here...
    Code:
    switch (crit) {
    		case 'a':
    		case 'A':
    			CritNum = 10;
    			break;
    		case 'b':
    		case 'B':
    			CritNum = 20;
    			break;
    		case 'c':
    		case 'C':
    			CritNum = 30;
    			break;
    		case 'd':
    		case 'D':
    			CritNum = 50;
    			break;
    		case 'e':
    		case 'E':
    			CritNum = 70;
    			break;
    		case 'f':
    		case 'F':
    			CritNum = 80;
    			break;
    		case 'g':
    		case 'G':
    			CritNum = 90;
    			break;
    		case 'h':
    		case 'H':
    			CritNum = 100;
    			break;
    		case 'i':
    		case 'I':
    			CritNum = 120;
    			break;
    		default:
    			CritNum = 0;
    			break;
    	}
    
    I think a fold of your lower/uppercases would be better, but if you want to do a switch with fall-through between cases it might be better to do it like that. The compiler might have optimized away the double assignments, and assignments are cheap anyway, but you were always setting CritNum twice. And there was the reversed c/C cases as RiskyMr pointed out.
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    Clicking Build in Xcode will not give you an error. It will only give you a warning. You may not have noticed it, even if it was there.

    In general, I prefer to always enable the Build Setting "Treat Warnings as Errors". You can find it in the Build Settings panel by searching for Treat Warnings.

    The only times I disable this setting is after I've seen and understood every warning, and I want to do something quickly. Turning it on when it's off is a good way to find mistakes you may have missed, yet which are still mistakes.
     
  9. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #9
    Lee210 - Thanks for that alternative code. I did not even think about that.

    Chown33 - I will implement that warning to error you recommended.

    Thanks guys!

    -Lars
     

Share This Page