Thread: Trouble with assignment in C

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    9

    Trouble with assignment in C

    Hi all,

    I'm having some trouble with an assignment where I have to encrypt or decrypt a four digit integer. The encryption and decryption isn't really a problem for me, it's the section for user options. Every time I come to the point where the user has the option to exit, I seem to have trouble executing that task. Please see below.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void encrypt(int number1);
    void decrypt(int number2);
    
    int main(void)
    {
    	int number;
    	char option, option2;
    
    	printf("Encode or Decode? (e/d)");
    	scanf("%c", &option);
    
    	if(option == 'e'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		encrypt(number);
    	}
    
    	else if(option == 'd'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		decrypt(number);
    	}
    	else{
    		printf("please choose an option.");
    	}
    
    	printf("\nContinue? (y/n) ");
    	scanf("%c", &option2);
    
    	if(option2 == 'y'){
    		do{
    			printf("Encode or Decode? (e/d)");
    			scanf("%c", &option);
    
    			if(option == 'e'){
    
    				printf("Enter four digit number: ");
    				scanf("%d", &number);
    				encrypt(number);
    			}
    
    			else if(option == 'd'){
    
    				printf("Enter four digit number: ");
    				scanf("%d", &number);
    				decrypt(number);
    			}
    
    			else{
    				printf("please choose an option.");
    			}
    			printf("\nContinue? (y/n) ");
    			scanf("%c", &option2);
    		}while(option2 != 'n');
    	}
    	else{
    		printf("Please remember to secure your password before exiting.\n");
    	}
    	system("pause");
    
    	return 0;
    }
    void encrypt(int number1)
    {
    
    	int i;
    	int j = 0;
    	int temp;
    	int code[4];
    	int a, b, c, d, m, n, o, p;
    
    	for(i = 1000; i >= 1; i /= 10){
    		temp = number1 % i;
    		code[j] = (number1 - temp) / i;
    		number1 = temp;
    		j++;
    	}
    	m = code[0];
    	n = code[1];
    	o = code[2];
    	p = code[3];
    	
    
    	m += 7,	n += 7,	o += 7,	p += 7;			 /*add 7 to digit*/
    
    	m %= 10, n %= 10, o %= 10, p %= 10;		 /*replace digit with remainder of 10*/
    
    	a = m * o/m;							 /*swap first digit with third*/
    	c = o * m/o;							 /*swap third digit with first*/
    
    	b = n * p/n;							 /*swap second digit with fourth*/
    	d = p * n/p;							 /*swap second digit with fourth*/
    
    	printf("Encrypted number is: %d%d%d%d", a, b, c, d); /*print new number*/
    }
    
    void decrypt(int number2)
    {
    	int t = 0;
    	int s;
    	int temp;
    	int code[4];
    	int a, b, c, d, i, j, k, l;
    
    	for(s = 1000; s >= 1; s /= 10){
    		temp = number2 % s;
    		code[t] = (number2 - temp) / s;
    		number2 = temp;
    		t++;
    	}
    	i = code[0];
    	j = code[1];
    	k = code[2];
    	l = code[3];
    
    	a = i * k/i;	/*swap first digit with third*/
    	c = k * i/k;	/*swap third digit with first*/
    
    	b = j * l/j;	/*swap second digit with fourth*/
    	d = l * j/l;	/*swap second digit with fourth*/
    
    	a += 3,	b += 3,	c += 3,	d += 3;	/*simplified - remainder of ten, then minus seven*/
    
    	printf("Decrypted number is: %d%d%d%d", a, b, c, d); /*print new number*/

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    When you ask scanf to read a character with %c, scanf line-buffers. That is, it waits until the user hits enter before returning. So say you type "y\n". scanf will read the 'y', store it in your character, and the program will continue merrily on its way. Now you call scanf again. But remember the buffer? scanf only read the 'y' from it, leaving the '\n' still in there. So this next scanf call goes to read a character, and sees that the '\n' is already there. It reads the '\n' and stores it in your character.

    Probably not what you want. You want to enter "y\n" at one prompt and then "n\n" at another, or something like that. So what you need to do is to strip the remaining characters from the input buffer after you read the character you're interested in.

    The easiest way to do this is as follows:
    Code:
    while(getchar() != '\n') {}
    Put that after your scanf %c calls, and the code should work. Of course, it can be improved on; if the user ever types CTRL-D/CTRL-Z/whatever for end of file, that's an infinite loop. So if you feel like it you can use
    Code:
    int c;
    while((c = getchar()) != '\n' && c != EOF) {}
    Oh, and it's always a good idea to check the return value of scanf(). If it returns 1, then it read one format specifier. If you asked scanf to read %d%d, then you'd expect the return value to be 2 upon success. And so on.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    scanf leaves the newline in the input buffer, after the first one change every "%c" to " %c"

    also, it divides by 0 quite a lot
    Last edited by ಠ_ಠ; 06-19-2009 at 10:11 PM.
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  4. #4
    Registered User
    Join Date
    Jun 2009
    Posts
    9
    Thanks very much for the help! It's greatly appreciated. I put in the code you sugested, and it helped me get past the first issue I was having. Now, should I put in a similar line like
    Code:
    while(getchar() != 'e'){}
    once the loop initiates? I'm having some trouble with that part.

    Thanks again all for the help!

    Matt

  5. #5
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    what are you talking about?
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  6. #6
    Registered User
    Join Date
    Jun 2009
    Posts
    9
    I changed the main body of the code I wrote to this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void encrypt(int number1);
    void decrypt(int number2);
    
    int main(void)
    {
    	int number;
    	char option, option2;
    
    	do{
    	printf("Encode or Decode? (e/d)\n");
    	scanf("%c", &option);
    
    	if(option == 'e'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		encrypt(number);
    	}
    
    	else if(option == 'd'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		decrypt(number);
    	}
    
    	printf("\nContinue? (y/n)\n");
    	scanf("%c", &option2);
    
    	}while(getchar() != 'n');
    		
    	printf("Please remember to secure your password before exiting.\n");
    
    	system("pause");
    
    	return 0;
    }
    This is what happens when I run the code.
    PHP Code:
    Encode or Decode? (e/d)
    e
    Enter four digit number
    4526
    Encrypted number is
    9312
    Continue? (y/n
    y
    Encode 
    or Decode? (e/d)

    Continue? (
    y/n
    Why does my program print "Encode or Decode?" without making a selection. I used
    Code:
    while(getchar() != 'n');
    at the end of my "do" loop. It's been driving me crazy.

    Thanks,

    Matt

  7. #7
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    Quote Originally Posted by mohanlon View Post
    I changed the main body of the code I wrote to this:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void encrypt(int number1);
    void decrypt(int number2);
    
    int main(void)
    {
    	int number;
    	char option, option2;
    
    	do{
    	printf("Encode or Decode? (e/d)\n");
    	scanf("%c", &option);
    
    	if(option == 'e'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		encrypt(number);
    	}
    
    	else if(option == 'd'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		decrypt(number);
    	}
    
    	printf("\nContinue? (y/n)\n");
    	scanf("%c", &option2);
    
    	}while(getchar() != 'n');
    		
    	printf("Please remember to secure your password before exiting.\n");
    
    	system("pause");
    
    	return 0;
    }
    This is what happens when I run the code.
    PHP Code:
    Encode or Decode? (e/d)
    e
    Enter four digit number
    4526
    Encrypted number is
    9312
    Continue? (y/n
    y
    Encode 
    or Decode? (e/d)

    Continue? (
    y/n
    Why does my program print "Encode or Decode?" without making a selection. I used
    Code:
    while(getchar() != 'n');
    at the end of my "do" loop. It's been driving me crazy.

    Thanks,

    Matt
    \n not n
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  8. #8
    Registered User
    Join Date
    Jun 2009
    Posts
    9
    I tried that too. It's the same thing happening.
    PHP Code:
    Encode or Decode? (e/d)
    e
    Enter four digit number
    4526
    Encrypted number is
    9312
    Continue? (y/n
    y
    Encode 
    or Decode? (e/d)

    Continue? (
    y/n)  
    y
    Please remember to secure your password before exiting
    .
    Press any key to continue... 
    What am I missing?

    Thanks,

    Matt

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    48
    I doubt whether the following is a satisfactory solution , but then mixing character input with numeric input has always been a bit tricky because of the * '\n' still there in buffer problem*
    May be someone could come up up with a FAR better solution.

    Code:
    .
    .
    int option, option2;
    
    do
    {
    	   printf("\nEncode or Decode? (e/d) ");
    	   option = getchar();
    
           while (getchar() !='\n')                   /*eats the '\n'*/
             ;
           printf ("\n You chose %c" ,option);
    
    	   if(option == 'e'){
    		   printf("\nEnter four digit number: ");
    		   scanf("%d", &number);
    		   encrypt(number);
            }
    
    	   else if(option == 'd'){
    		   printf("\nEnter four digit number: ");
    		   scanf("%d", &number);
    		   decrypt(number);
    	}
        while ( getchar()!= '\n') /*what if one of your functions starts taking numeric input*/
    	;
    	printf("\nContinue? (y/n) ");
    
    	option2 = getchar();
        printf ("\n You chose %c" ,option2);
    
        while ( getchar()!= '\n')
    	;
    }
    	while(option2 == 'y'); /*Don't you want to check for a y instead of checking for '\n'*/
    .
    ./*May be you could put that 
                       while (getchar() !='\n');
        part in a function and call it eat_bad_chars() nd use it again and again
    */
    While another option would be to take only numeric inputs and then 'tweak' the program and ask the user in the form of numbers like
    1. Encode
    2. Decode
    .
    .
    Continue (1. Yes 2.No)
    Something of that sort if its allowed
    Code:
    .
    .
    int option, option2;
    
    	do
    	{
    	   printf("\n1.Encode \t2. Decode?" );
    	   ;
    	   scanf ("%d" , &option);
    
           printf ("\n You chose %d" ,option);
    
    	   if(option == 1){
    		   printf("\nEnter four digit number: ");
    		   scanf("%d", &number);
    		   encrypt(number);
            }
    
    	   else if(option == 2){
    		   printf("\nEnter four digit number: ");
    		   scanf("%d", &number);
    		   decrypt(number);
    	}
    
    	printf("\nContinue? (1.Yes\t2.No) ");
    
    	scanf ("%d" ,&option2);
        printf ("\n You chose %d" ,option2);
    
    
    }
    	while(option2 == 1);
    Sample run

    1.Encode 2. Decode?1

    You chose 1
    Enter four digit number: 4526
    Encrypted number is: 9312
    Continue? (1.Yes 2.No) 1

    You chose 1
    1.Encode 2. Decode?1

    You chose 1
    Enter four digit number: 4589
    Encrypted number is: 5612
    Continue? (1.Yes 2.No) 2

    You chose 2Please remember to secure your password before exiting.

    Last edited by zalezog; 06-20-2009 at 01:58 PM.

  10. #10
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    your not using while(getchar() != '\n') {} correctly, put it before and after you ask the user if they want to continue
    Code:
        while(getchar() != '\n') {}
        scanf("%c", &option2);
        while(getchar() != '\n') {}
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Not necessarily. If you did that twice in a row you'd have
    Code:
        while(getchar() != '\n') {}
        scanf("%c", &option2);
        while(getchar() != '\n') {}
        while(getchar() != '\n') {}
        scanf("%c", &option2);
        while(getchar() != '\n') {}
    which would cause the program to ignore every other line of input.

    Just putting the character-eating code right after every scanf() call will probably do what you want. I've modified your original code to be this way, though I'm not sure if it works because I'm not certain what it's supposed to do.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void strip_characters(void);
    void encrypt(int number1);
    void decrypt(int number2);
    
    int main(void)
    {
    	int number;
    	char option, option2;
    
    	printf("Encode or Decode? (e/d)");
    	scanf("%c", &option);
    	strip_characters();
    
    	if(option == 'e'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		strip_characters();
    		encrypt(number);
    	}
    
    	else if(option == 'd'){
    		printf("Enter four digit number: ");
    		scanf("%d", &number);
    		strip_characters();
    		decrypt(number);
    	}
    	else{
    		printf("please choose an option.");
    	}
    
    	printf("\nContinue? (y/n) ");
    	scanf("%c", &option2);
    	strip_characters();
    
    	if(option2 == 'y'){
    		do{
    			printf("Encode or Decode? (e/d)");
    			scanf("%c", &option);
    			strip_characters();
    
    			if(option == 'e'){
    
    				printf("Enter four digit number: ");
    				scanf("%d", &number);
    				strip_characters();
    				encrypt(number);
    			}
    
    			else if(option == 'd'){
    
    				printf("Enter four digit number: ");
    				scanf("%d", &number);
    				strip_characters();
    				decrypt(number);
    			}
    
    			else{
    				printf("please choose an option.");
    			}
    			printf("\nContinue? (y/n) ");
    			scanf("%c", &option2);
    			strip_characters();
    		}while(option2 != 'n');
    	}
    	else{
    		printf("Please remember to secure your password before exiting.\n");
    	}
    	system("pause");
    
    	return 0;
    }
    
    void strip_characters(void) {
        int disregard;
        
        do {
            disregard = getchar();
        } while(disregard != '\n' && disregard != EOF);
    }
    
    void encrypt(int number1)
    {
    
    	int i;
    	int j = 0;
    	int temp;
    	int code[4];
    	int a, b, c, d, m, n, o, p;
    
    	for(i = 1000; i >= 1; i /= 10){
    		temp = number1 % i;
    		code[j] = (number1 - temp) / i;
    		number1 = temp;
    		j++;
    	}
    	m = code[0];
    	n = code[1];
    	o = code[2];
    	p = code[3];
    	
    
    	m += 7,	n += 7,	o += 7,	p += 7;			 /*add 7 to digit*/
    
    	m %= 10, n %= 10, o %= 10, p %= 10;		 /*replace digit with remainder of 10*/
    
    	a = m * o/m;							 /*swap first digit with third*/
    	c = o * m/o;							 /*swap third digit with first*/
    
    	b = n * p/n;							 /*swap second digit with fourth*/
    	d = p * n/p;							 /*swap second digit with fourth*/
    
    	printf("Encrypted number is: %d%d%d%d", a, b, c, d); /*print new number*/
    }
    
    void decrypt(int number2)
    {
    	int t = 0;
    	int s;
    	int temp;
    	int code[4];
    	int a, b, c, d, i, j, k, l;
    
    	for(s = 1000; s >= 1; s /= 10){
    		temp = number2 % s;
    		code[t] = (number2 - temp) / s;
    		number2 = temp;
    		t++;
    	}
    	i = code[0];
    	j = code[1];
    	k = code[2];
    	l = code[3];
    
    	a = i * k/i;	/*swap first digit with third*/
    	c = k * i/k;	/*swap third digit with first*/
    
    	b = j * l/j;	/*swap second digit with fourth*/
    	d = l * j/l;	/*swap second digit with fourth*/
    
    	a += 3,	b += 3,	c += 3,	d += 3;	/*simplified - remainder of ten, then minus seven*/
    
    	printf("Decrypted number is: %d%d%d%d", a, b, c, d); /*print new number*/
    }
    It's a bit of a hassle, isn't it? The alternative is to read input in line by line with fgets(), and then use sscanf() to parse what you want from the line. That way you never have to discard characters from the input.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    Quote Originally Posted by dwks View Post
    It's a bit of a hassle, isn't it? The alternative is to read input in line by line with fgets(), and then use sscanf() to parse what you want from the line. That way you never have to discard characters from the input.
    or put a space after the %c ("%c ") to eat up the \n
    Last edited by ಠ_ಠ; 06-20-2009 at 04:25 PM.
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  13. #13
    Registered User
    Join Date
    Jun 2009
    Posts
    9
    ಠ_ಠ, dwks, & zalezog,

    Thanks so much! I wasn't fully aware of how scanf and getchar() stores a newline as a character in a buffer, so I misunderstood it all at first. I understand it now, and I ended up putting it in a function (void eat_newline(void)) which is much easier to handle since it's used so much. Again, many thanks, I've been working on that one since yesterday evening and it's been killing me!

  14. #14
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Why not just start the loop then ask questions? I just moved the code around ... I am not looking into function use like the other guys, so you'll want to make those updates.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void encrypt(int number1);
    void decrypt(int number2);
    
    int main(void)
    {
    	int number;
    	char option, option2;
    
    	do{
    		printf("Encode or Decode? (e/d)");
    		scanf("%c", &option);
    
    		if(option == 'e'){
    
    			printf("Enter four digit number: ");
    			scanf("%d", &number);
    			encrypt(number);
    		}
    
    		else if(option == 'd'){
    
    			printf("Enter four digit number: ");
    			scanf("%d", &number);
    			decrypt(number);
    		}
    		
    		else if(option == 'n'){
                           printf("Bye.");
                           system("PAUSE");
                           return 0;     
                   }
    
    		else{
    			printf("please choose an option.");
    		}
    		printf("\nContinue? (y/n) ");
    		scanf("%c", &option2);
    	}while(option2 != 'n');
    
    	return 0;
    }

  15. #15
    Registered User
    Join Date
    Mar 2009
    Posts
    48
    @Kudose Here's what you'd get after you run the code(#14).Probably you missed the whole point about the thread.


    Encode or Decode? (e/d)e
    Enter four digit number: 4526
    Encrypted number is: 9312
    Continue? (y/n) Encode or Decode? (e/d)e
    Enter four digit number: 4521
    Encrypted number is: 9812
    Continue? (y/n) Encode or Decode? (e/d)e
    Enter four digit number: 1211
    Encrypted number is: 8889
    Continue? (y/n) Encode or Decode? (e/d)d
    Enter four digit number: 4529
    Decrypted number is: 51278
    Continue? (y/n) Encode or Decode? (e/d)
    please choose an option.
    Continue? (y/n)
    Encode or Decode? (e/d)
    please choose an option.
    Continue? (y/n)
    Encode or Decode? (e/d)
    .
    .

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Menu
    By Krush in forum C Programming
    Replies: 17
    Last Post: 09-01-2009, 02:34 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. Help with a pretty big C++ assignment
    By wakestudent988 in forum C++ Programming
    Replies: 1
    Last Post: 10-30-2006, 09:46 PM
  4. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  5. trouble with assignment, vectors..
    By bluegoo06 in forum C++ Programming
    Replies: 6
    Last Post: 11-16-2005, 03:43 PM

Tags for this Thread