C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 06-19-2009, 09:34 PM   #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*/
mohanlon is offline   Reply With Quote
Old 06-19-2009, 10:04 PM   #2
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,698
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.
dwks is offline   Reply With Quote
Old 06-19-2009, 10:08 PM   #3
Banned
 
ಠ_ಠ's Avatar
 
Join Date: Mar 2009
Posts: 533
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.
ಠ_ಠ is offline   Reply With Quote
Old 06-20-2009, 11:26 AM   #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
mohanlon is offline   Reply With Quote
Old 06-20-2009, 12:08 PM   #5
Banned
 
ಠ_ಠ's Avatar
 
Join Date: Mar 2009
Posts: 533
what are you talking about?
__________________
╔╗╔══╦╗
║║║╔╗║║
║╚╣╚╝║╚╗
╚═╩══╩═╝
ಠ_ಠ is offline   Reply With Quote
Old 06-20-2009, 12:32 PM   #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
mohanlon is offline   Reply With Quote
Old 06-20-2009, 12:42 PM   #7
Banned
 
ಠ_ಠ's Avatar
 
Join Date: Mar 2009
Posts: 533
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
__________________
╔╗╔══╦╗
║║║╔╗║║
║╚╣╚╝║╚╗
╚═╩══╩═╝
ಠ_ಠ is offline   Reply With Quote
Old 06-20-2009, 12:55 PM   #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
mohanlon is offline   Reply With Quote
Old 06-20-2009, 01:56 PM   #9
Registered User
 
Join Date: Mar 2009
Posts: 38
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.
zalezog is offline   Reply With Quote
Old 06-20-2009, 02:13 PM   #10
Banned
 
ಠ_ಠ's Avatar
 
Join Date: Mar 2009
Posts: 533
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') {}
__________________
╔╗╔══╦╗
║║║╔╗║║
║╚╣╚╝║╚╗
╚═╩══╩═╝
ಠ_ಠ is offline   Reply With Quote
Old 06-20-2009, 04:19 PM   #11
Frequently Quite Prolix
 
dwks's Avatar
 
Join Date: Apr 2005
Location: Canada
Posts: 7,698
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.
dwks is offline   Reply With Quote
Old 06-20-2009, 04:22 PM   #12
Banned
 
ಠ_ಠ's Avatar
 
Join Date: Mar 2009
Posts: 533
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.
ಠ_ಠ is offline   Reply With Quote
Old 06-20-2009, 05:21 PM   #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!
mohanlon is offline   Reply With Quote
Old 06-21-2009, 07:08 AM   #14
Registered User
 
Join Date: Jun 2006
Posts: 83
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;
}
Kudose is offline   Reply With Quote
Old 06-21-2009, 08:38 AM   #15
Registered User
 
Join Date: Mar 2009
Posts: 38
@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)
.
.
zalezog is offline   Reply With Quote
Reply

Tags
[code]

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Menu Krush C Programming 17 09-01-2009 02:34 AM
Screwy Linker Error - VC2005 Tonto C++ Programming 5 06-19-2007 02:39 PM
Help with a pretty big C++ assignment wakestudent988 C++ Programming 1 10-30-2006 09:46 PM
A mini-compilier I made stuck in an infinite loop (lots of code) dan06 C++ Programming 1 10-27-2006 01:21 PM
trouble with assignment, vectors.. bluegoo06 C++ Programming 6 11-16-2005 03:43 PM


All times are GMT -6. The time now is 09:28 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22