Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.
Damn, I still can't do it. What is wrong? Where does it want a ; before a { token? According to the compiler!!! I have an opening bracket a semi, and a closing bracket for each one. So what the heck? And do I need a return 0 at the end of the if statement block?

my terminal/compiler shows this

Code:
Users/scottdean/documents/number2number.c: In function ‘main’:
/Users/scottdean/documents/number2number.c:37: error: expected ‘;’ before ‘{’ token


Code:
#include <stdio.h>

main () 
{

	int first_number, second_number, number ;
	
	
	printf ("Enter a two digit number: ") ;
	scanf ("%d", &number) ;
	
	
	if (number == 11) {
		printf ("eleven\n") ;
		}
    else if (number == 12) {
		printf ("twelve\n") ;
		}
	else if (number == 13) {
		printf ("thirteen\n") ;
		}
	else if (number == 14) {
		printf ("fourteen\n") ;
		}
	else if (number == 15) {
		printf ("fifteen\n") ;
		}
	else if (number == 16) {
		printf ("sixteen\n") ;
		}
	else if (number == 17) {
		printf ("seventeen\n") ;
	    }
	else if (number == 18) {
		printf ("eighteen\n") ;
		}
	else (number == 19) {
		printf ("nineteen\n") ;
		}
		
		
		
		
		printf ("You Entered the Number %d\n", number) ;
		first_number = number / 10 ;
	    second_number = number % 10 ;
	
	switch (first_number) {
		case 9: printf ("ninety-"); break;
		case 8: printf ("eighty-"); break;
		case 7: printf ("seventy-"); break;
		case 6: printf ("sixty-"); break;
		case 5: printf ("fifty-"); break;
		case 4: printf ("forty-"); break;
		case 3: printf ("thirty-"); break;
		case 2: printf ("twenty-"); break;
		}
		
	switch (second_number) {
		case 9: printf ("nine\n"); break;
		case 8: printf ("eight\n"); break;
		case 7: printf ("seven\n"); break;
		case 6: printf ("six\n"); break;
		case 5: printf ("five\n"); break;
		case 4: printf ("four\n"); break;
		case 3: printf ("three\n"); break;
		case 2: printf ("two\n"); break;
		case 1: printf ("one\n"); break;
		}
		
		
	
	
	return 0 ;
	
	}
 
This is last nights code, do I just copy this only with == instead of relational operators?


Code:
if (a > 100 || a < 0) {
		printf ("error, error, Danger Will Robinson! Danger!!\n") ;
		return 0 ;
		}
 
I changed the code to look (format wise) just like last nights, but it still doesn't work!!:eek::eek::eek::eek::eek::eek:

See what i mean, try try try a million different ways and nothing works, and here it is almost 4 am again. ouch!



Code:
	if (number == 11) {
		printf ("eleven\n") ;
		return 0 ;
		}
    else if (number == 12) {
		printf ("twelve\n") ;
		return 0 ;
		}
	else if (number == 13) {
		printf ("thirteen\n") ;
		return 0 ;
		}
	else if (number == 14) {
		printf ("fourteen\n") ;
		return 0 ;
		}
	else if (number == 15) {
		printf ("fifteen\n") ;
		return 0 ;
		}
	else if (number == 16) {
		printf ("sixteen\n") ;
		return 0 ;
		}
	else if (number == 17) {
		printf ("seventeen\n") ;
		return 0 ;
	    }
	else if (number == 18) {
		printf ("eighteen\n") ;
		return 0 ;
		}
	else (number == 19) {
		printf ("nineteen\n") ;
		return 0 ;
		}
 
Okay fixed that if. It's better now, getting closer, but still not exactly right.

Compiler output: As you can see, the non 11-19 print as "You entered the number 45 forty-five." It should just say "You entered the number forty-five."

And the 11 below, just says "eleven" and isn't including the printf of "You entered the number" (For this case, I could just edit the printf to say "You entered the number eleven", instead of just "eleven" as it is currently. But is that the only way to do it? Or can I have that "eleven" inserted into the printf statement I have further down the page, the one that the switch cases are using?

Code:
Scott-Deans-MacBook-Pro:~ scottdean$ gcc ~/documents/number2number.c
Scott-Deans-MacBook-Pro:~ scottdean$ ./a.out
Enter a two digit number: 45
You Entered the Number 45
forty-five
Scott-Deans-MacBook-Pro:~ scottdean$ ./a.out
Enter a two digit number: 99
You Entered the Number 99
ninety-nine
Scott-Deans-MacBook-Pro:~ scottdean$ ./a.out
Enter a two digit number: 20
You Entered the Number 20
twenty-Scott-Deans-MacBook-Pro:~ scottdean$ ./a.out
Enter a two digit number: 11
eleven
Scott-Deans-MacBook-Pro:~ scottdean$ ./a.out
Enter a two digit number: 15
fifteen
Scott-Deans-MacBook-Pro:~ scottdean$






Code:
if (number == 11) {
		printf ("eleven\n") ;
		return 0 ;
		}
    else if (number == 12) {
		printf ("twelve\n") ;
		return 0 ;
		}
	else if (number == 13) {
		printf ("thirteen\n") ;
		return 0 ;
		}
	else if (number == 14) {
		printf ("fourteen\n") ;
		return 0 ;
		}
	else if (number == 15) {
		printf ("fifteen\n") ;
		return 0 ;
		}
	else if (number == 16) {
		printf ("sixteen\n") ;
		return 0 ;
		}
	else if (number == 17) {
		printf ("seventeen\n") ;
		return 0 ;
	    }
	else if (number == 18) {
		printf ("eighteen\n") ;
		return 0 ;
		}
	else if (number == 19) {
		printf ("nineteen\n") ;
		return 0 ;
		}
 
Code:
	else (number == 19) {
		printf ("nineteen\n") ;
		return 0 ;
		}

Missing "if" before "(number == 19)"

The textbook is probably poor at explaining C syntax, which makes the error message, no ";" before "{" seem very cryptic. What you might be thinking of as an assignment statement is actually an expression statement -- any valid expression, even without an assignment, is valid. Expression statements always end with a semicolon. The syntax of an if statement is:
if (expression) statement
or
if (expression) statement else statement

so that final "else" is followed by a statement, "(number==19)". However this is an expression statement and needs to be followed by a semicolon, which is missing!

When you add the "if" the statement following "else" is another if statement and it will compile correctly.
 
Here is the entire program again, and I changed the first printf in the first "if" statement to show what i meant. Of course this is one way to get my 11 -19 perfect, but I was wondering if I could just get the "eleven" or "twelve", etc, to insert into the following printf further down the page that the switch stmtns are using?

So now that I changed the eleven, all the special cases are okay.

But now how to fix the non special ones so they don't print like they are.
"You entered the number 45 forty-five" should be....
"You entered the number forty-five"

Code:
#include <stdio.h>

main () 
{

	int first_number, second_number, number ;
	
	
	printf ("Enter a two digit number: ") ;
	scanf ("%d", &number) ;
	
	
	if (number == 11) {
		printf ("You entered the number eleven\n") ;
		return 0 ;
		}
    else if (number == 12) {
		printf ("twelve\n") ;
		return 0 ;
		}
	else if (number == 13) {
		printf ("thirteen\n") ;
		return 0 ;
		}
	else if (number == 14) {
		printf ("fourteen\n") ;
		return 0 ;
		}
	else if (number == 15) {
		printf ("fifteen\n") ;
		return 0 ;
		}
	else if (number == 16) {
		printf ("sixteen\n") ;
		return 0 ;
		}
	else if (number == 17) {
		printf ("seventeen\n") ;
		return 0 ;
	    }
	else if (number == 18) {
		printf ("eighteen\n") ;
		return 0 ;
		}
	else if (number == 19) {
		printf ("nineteen\n") ;
		return 0 ;
		}
		
		
		
		
		printf ("You Entered the Number %d\n", number) ;
		first_number = number / 10 ;
	    second_number = number % 10 ;
	
	switch (first_number) {
		case 9: printf ("ninety-"); break;
		case 8: printf ("eighty-"); break;
		case 7: printf ("seventy-"); break;
		case 6: printf ("sixty-"); break;
		case 5: printf ("fifty-"); break;
		case 4: printf ("forty-"); break;
		case 3: printf ("thirty-"); break;
		case 2: printf ("twenty-"); break;
		}
		
	switch (second_number) {
		case 9: printf ("nine\n"); break;
		case 8: printf ("eight\n"); break;
		case 7: printf ("seven\n"); break;
		case 6: printf ("six\n"); break;
		case 5: printf ("five\n"); break;
		case 4: printf ("four\n"); break;
		case 3: printf ("three\n"); break;
		case 2: printf ("two\n"); break;
		case 1: printf ("one\n"); break;
		}
		
		
	
	
	return 0 ;
	
	}
 
Okay fixed that if. It's better now, getting closer, but still not exactly right.

Compiler output: As you can see, the non 11-19 print as "You entered the number 45 forty-five." It should just say "You entered the number forty-five."

It's doing exactly what you are telling it to. The line in the program:
Code:
		printf ("You Entered the Number %d\n", number) ;

should probably be:
Code:
		printf ("You Entered the Number ") ;

and should probably be placed before any of the other printf calls.
 
And the 11 below, just says "eleven" and isn't including the printf of "You entered the number"

It looks like you might be getting lost in the forest.

There is no "You entered the number" before "eleven" because the statement that prints "You entered the number" is located after the statement that prints "eleven".

Furthermore, the statement that prints "eleven" is in a block where a return is executed after printing "eleven". If you return, then no further statements in the entire function will be executed.

I think you'd be able to figure it out better by making the problem smaller, say only handle eleven and twelve. Make that smaller one work. Then add thirteen and make sure it still works. Repeat with fourteen, fifteen, etc.


You also seem to be trying brute force to solve the whole problem at once, instead of breaking it down into smaller problems. For example, the eleven problem is solved, but you still haven't solved it for twelve. You need to break it down into two parts:
1. Print "You entered the number" before anything else.
2. Print the number that was entered.

You then break #2 down into one part for 11-19 and a part for other values.

If you don't break it down, you'll never get anywhere, because the problem you're trying to solve will be too big and spread out.

Breaking it down isn't just to make coding it easier. It's part of the thought process of solving problems. In many ways, learning the programming language is the easier task; it's learning the thought processes like breaking it down (Decomposition) and building blocks (Composition) that are the hard part.
http://en.wikipedia.org/wiki/Decomposition_(computer_science)
http://en.wikipedia.org/wiki/Object_composition


It's unclear to me whether the book has told you how to make separate functions other than main(), but if it has, now would be a good time to do so. Separate functions helps make it easier to see what the high-level logic is doing (e.g. separate it into "categories" of 1-10, 11-19, 20 and up). Then each function handles only the values appropriate to it: one function for 1-10, another function for 11-19, another function for 20 and up.
 
Last edited:
Missing "if" before "(number == 19)"

The textbook is probably poor at explaining C syntax, which makes the error message, no ";" before "{" seem very cryptic. What you might be thinking of as an assignment statement is actually an expression statement -- any valid expression, even without an assignment, is valid. Expression statements always end with a semicolon. The syntax of an if statement is:
if (expression) statement
or
if (expression) statement else statement

so that final "else" is followed by a statement, "(number==19)". However this is an expression statement and needs to be followed by a semicolon, which is missing!

When you add the "if" the statement following "else" is another if statement and it will compile correctly.


Ahhh, I see what you mean. without the "if" the compiler thinks I'm doing something different, so it is looking for a semi in that scenario, but when I add the missing "if" instead, it no longer is looking for the semi, because I changed the expression/statement.

I told the compiler (something), and it said in return (your missing a semi)
but I told it the wrong thing, then
I told the compiler (something different/the right thing), and it changed it's response to me, no longer looking for a semi, and compiling my code.

Think I got it!
 
Here's an approach that doesn't require all of those icky (IMHO) returns.

Code:
#include <stdio.h>

int main(int argc, char *argv) {

  int number;
        
  printf ("Enter number (0-100): ") ;
  scanf ("%d", &number ) ;  

  if ((number >= 0) && (number <= 100)) {
    int ones, tens;
    
    printf ("You entered the number ", number) ;  
    ones = number % 10;
    tens = number / 10;
        
    if ((number >= 10 ) && (number <= 19)) {
      switch (ones) {
      case 9: printf ("nineteen\n"); break;
      case 8: printf ("eighteen\n"); break;
      case 7: printf ("seventeen\n"); break;
      case 6: printf ("sixteen\n"); break;
      case 5: printf ("fifteen\n"); break;
      case 4: printf ("fourteen\n"); break;
      case 3: printf ("thirteen\n"); break;
      case 2: printf ("twelve\n"); break;
      case 1: printf ("eleven\n"); break;
      case 0: printf ("ten\n"); break;
      }
      }
      else if (number == 0) printf ("zero\n");
      else {
        switch (tens) {
        case 9: printf ("ninety-"); break;
        case 8: printf ("eighty-"); break;
        case 7: printf ("seventy-"); break;
        case 6: printf ("sixty-"); break;
        case 5: printf ("fifty-"); break;
        case 4: printf ("forty-"); break;
        case 3: printf ("thirty-"); break;
        case 2: printf ("twenty-"); break;
        case 1: break;
        case 0: break;
        }
                
        switch (ones) {
        case 9: printf ("nine\n"); break;
        case 8: printf ("eight\n"); break;
        case 7: printf ("seven\n"); break;
        case 6: printf ("six\n"); break;
        case 5: printf ("five\n"); break;
        case 4: printf ("four\n"); break;
        case 3: printf ("three\n"); break;
        case 2: printf ("two\n"); break;
        case 1: printf ("one\n"); break;
        case 0: break;
        }        
      }
  }
  else printf ("ERROR: Score is out of range 0-100\n");

  return 0;
}

B
 
It looks like you might be getting lost in the forest.

It's unclear to me whether the book has told you how to make separate functions other than main(), but if it has, now would be a good time to do so. Separate functions helps make it easier to see what the high-level logic is doing (e.g. separate it into "categories" of 1-10, 11-19, 20 and up). Then each function handles only the values appropriate to it: one function for 1-10, another function for 11-19, another function for 20 and up.

No, the book has only covered main () so far, only on Chapter 5. Hoping to one day get to chapter 6! ! LOL :D

Thanks!
 
Here's an approach that doesn't require all of those icky (IMHO) returns.

Code:
#include <stdio.h>

int main(int argc, char *argv) {

  int number;
        
  printf ("Enter number (0-100): ") ;
  scanf ("%d", &number ) ;  

  if ((number >= 0) && (number <= 100)) {
    int ones, tens;
    
    printf ("You entered the number ", number) ;  
    ones = number % 10;
    tens = number / 10;
        
    if ((number >= 10 ) && (number <= 19)) {
      switch (ones) {
      case 9: printf ("nineteen\n"); break;
      case 8: printf ("eighteen\n"); break;
      case 7: printf ("seventeen\n"); break;
      case 6: printf ("sixteen\n"); break;
      case 5: printf ("fifteen\n"); break;
      case 4: printf ("fourteen\n"); break;
      case 3: printf ("thirteen\n"); break;
      case 2: printf ("twelve\n"); break;
      case 1: printf ("eleven\n"); break;
      case 0: printf ("ten\n"); break;
      }
      }
      else if (number == 0) printf ("zero\n");
      else {
        switch (tens) {
        case 9: printf ("ninety-"); break;
        case 8: printf ("eighty-"); break;
        case 7: printf ("seventy-"); break;
        case 6: printf ("sixty-"); break;
        case 5: printf ("fifty-"); break;
        case 4: printf ("forty-"); break;
        case 3: printf ("thirty-"); break;
        case 2: printf ("twenty-"); break;
        case 1: break;
        case 0: break;
        }
                
        switch (ones) {
        case 9: printf ("nine\n"); break;
        case 8: printf ("eight\n"); break;
        case 7: printf ("seven\n"); break;
        case 6: printf ("six\n"); break;
        case 5: printf ("five\n"); break;
        case 4: printf ("four\n"); break;
        case 3: printf ("three\n"); break;
        case 2: printf ("two\n"); break;
        case 1: printf ("one\n"); break;
        case 0: break;
        }        
      }
  }
  else printf ("ERROR: Score is out of range 0-100\n");

  return 0;
}

B

Yeah it looks interesting, more than one way to skin a cat for sure, it's amazing how complicated it really is to just change a number 45, into forty-five, so much code for such a simple thing. I need to learn some more about your code first, such as int main(int argc, char *argv) i don't know any of those yet. I kinda get the char one, because somebody used it with me once before, but I don't know all about how to use it or when, nor do I know argc, and *argv. I need it explained. People have referred me countless times to the C standard library or the ISO/IEC 9899:TC3 document, but I don't have the knowledge yet to understand how to read and comprehend those documents. 99% of what's in them means nothing to me yet.
 
Here's an approach that doesn't require all of those icky (IMHO) returns.

I can see why you like only having one return statement in a function, but I don't like it. I think it creates too many levels of indenting and you soon get lines longer than 80 characters or have to put messy breaks in lines. I don't think this makes programs easier to read at all. If you have an error test at the start of a function, I think it's neater to return there for an error. Otherwise the rest of the function (most of it) is indented one more level in an 'else' block needlessly.

Even apple does it the way I like, e.g.

Code:
- (id)init {
   if (![super init]) {
      return nil;
   }
}

I've never seen anyone else complain about excessive indenting, maybe it's just me...
 
so much code for such a simple thing.

You would never do this this way in practice. There are other code structures that would eliminate all of the switch/case/break statements and turn them into one line or maybe two, but you need to learn about enums, arrays and all that when you get to them.

I need to learn some more about your code first ... I need it explained.

This is one of the reasons I'm not sure I like the book you are using for your self-learning excercise. It may be great if used in a course with an instructor, but seems lacking in some of the basics.

I should really be using
Code:
int main (void)
in this code to say this code takes no arguments when executed from the command line (void) and returns a value of type int (that's what the "return 0;" in all your code does.

The argc/argv are containers to take in optional parameters from the command line when you execute the program from the command line. For example you could skip the scanf and pass the number to be parsed on the command line when you execute the program. If the executable is called "numberinwords", you could run
Code:
./numberinwords 42
to get it to say
Code:
You entered the number forty-two
Here, they do nothing since I don't use the values in my code.

B
 
I can see why you like only having one return statement in a function, but I don't like it. I think it creates too many levels of indenting and you soon get lines longer than 80 characters or have to put messy breaks in lines.

Each of those indented sections should be interpreted as a separate function, but cybrscot doesn't have the tools, yet.

e.g.

Code:
#include <stdio.h>

int main(int argc, char *argv) {

  int number;
        
  printf ("Enter number (0-100): ") ;
  scanf ("%d", &number ) ;  

  if ((number >= 0) && (number <= 100)) {
    int ones, tens;
    
    printf ("You entered the number ", number) ;  
    ones = number % 10;
    tens = number / 10;
        
    if ((number >= 10 ) && (number <= 19))  printspecials(ones);
    else if (number == 0) printzero;
    else printstandard(tens,ones);
  }
  else printerror;

  return 0;
}

EDIT: I missed one, and screwed up the range check since I took the code from the grade one, my typical actual code for this would look like:

Code:
#include <stdio.h>

int main(int argc, char *argv) {

  int number;
        
  printf ("Enter number (0-99): ") ;
  scanf ("%d", &number ) ;  

  int isinrange = ((number >= 0) && (number <= 99));

  if (isinrange) printtwodigitword(number);
  else printerror;

  return 0;
}
B
 
Last edited:
Yeah it looks interesting, more than one way to skin a cat for sure, it's amazing how complicated it really is to just change a number 45, into forty-five, so much code for such a simple thing.

Think about the libraries that convert a GPS location into a street address.
 
... it's amazing how complicated it really is to just change a number 45, into forty-five, so much code for such a simple thing.

Sometimes, that complexity is a hint that some other representation may be better suited. For example, large switch statements may be converted to arrays of data, with much smaller code that interprets the data. For example, this switch:

Code:
        switch (ones) {
        case 9: printf ("nine\n"); break;
        case 8: printf ("eight\n"); break;
        case 7: printf ("seven\n"); break;
        case 6: printf ("six\n"); break;
        case 5: printf ("five\n"); break;
        case 4: printf ("four\n"); break;
        case 3: printf ("three\n"); break;
        case 2: printf ("two\n"); break;
        case 1: printf ("one\n"); break;
        case 0: break;
        }
can be transformed into code that uses an array (warning: untested):
Code:
static char * ones_words[] =
  { "", "one", "two", "three", "four",
   "five", "six", "seven", "eight", "nine" };

printf( "%s\n", ones_words[ ones ] );

Similar transformations can be made for the "teens-words" and the "tens-words".

I don't expect you to understand the array-based code yet. My point is that with the limited capabilities available, many things which seem to be complicated are only complicated because you haven't been told about any other ways of doing them.

As another example, I would definitely have factored this whole thing into separate functions for hundreds, tens, teens, and units. A single giant main() function is so primitive it'd be like going to a restaurant and getting flint knives and sharpened sticks instead of tableware.
 
Pseudocode

Long ago, guys, I learned an important lesson: The sooner you write your program the buggier it'll be. Plan, plan, plan. Think out the problem in natural language before you write even one program line. If you're like me, you hate debugging because it frustrates you. Since it frustrates me, I do all I can to avoid it. Sometimes I can hardly balance my checkbook, let along debug a program. ;)
 
Code:
#include <stdio.h>

int main(void)
{
	int n,d;
	char *names[] = {"zero","one","two","three","four","five","six","seven",
"eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen",
"sixteen","seventeen","eighteen","nineteen"};
	char *tens[] = {"","","twenty","thirty","forty","fifty","sixty","seventy",
"eighty","ninety"};

	do
	{
		printf("Enter a number 0-99: ");
		scanf("%d",&n);
	} while((n<0) || (n>99));

	if(n<20) 
		puts(names[n]);
	else
	{
		d = n / 10;
		n = n % 10;
		if(!n)
			puts(tens[d]);
		else
			printf("%s-%s\n",tens[d],names[n]);
	}

	return 0;
}

Have fun!

As chown33 pointed out, switch introduces a hell of comparisons which are costly performancewise. Since all cases are neatly arranged (1,2,3,4,5...), it's easier to use a vector approach. Accessing the element of an array involves a single multiplication (which is handled by the compiler) instead of doing umpteen comparisons. Also looks cleaner, don't you think?

Recommended reading: "Beautiful Code" (O'Reilly), "Algorithms is C" (R. Sedgewick).
 
Last edited:
You would never do this this way in practice. There are other code structures that would eliminate all of the switch/case/break statements and turn them into one line or maybe two, but you need to learn about enums, arrays and all that when you get to them.

Sometimes, that complexity is a hint that some other representation may be better suited. For example, large switch statements may be converted to arrays of data, with much smaller code that interprets the data.

...

I don't expect you to understand the array-based code yet. My point is that with the limited capabilities available, many things which seem to be complicated are only complicated because you haven't been told about any other ways of doing them.

As chown33 pointed out, switch introduces a hell of comparisons which are costly performancewise. Since all cases are neatly arranged (1,2,3,4,5...), it's easier to use a vector approach. Accessing the element of an array involves a single multiplication (which is handled by the compiler) instead of doing umpteen comparisons. Also looks cleaner, don't you think?

I'm surprised that both of you went for an array instead of an enum. :p

cybrscot. Worry less about performance and more about the plan of attack at this point. As many of us in the thread have mentioned, plan before you write any code.

You need to learn to walk before you can run.

(I'm waiting for Beautiful Code to be a Deal of the Day or to need to buy to other full price eBooks, but it's on my list.).

B
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.