CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Binding Data to Silverlight 4.0 Controls Using ASP.NET MVC Framework 2.0
  • ADO.NET Data Services in the .NET Framework
  • Visual C++ Programming: What's new for MFC library in VC++ 2010?
  • Microsoft Visual Studio LightSwitch and What It Can Do For You

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    C++ (Non Visual C++ Issues) Ask or answer C and C++ questions not related to Visual C++. This includes Console programming, Linux programming, or general ANSI C++.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old July 16th, 2009, 02:50 AM
    mikesnuggets22 mikesnuggets22 is offline
    Junior Member
     
    Join Date: Jul 2009
    Posts: 6
    mikesnuggets22 is an unknown quantity at this point (<10)
    Encryption Program Problem

    Having trouble with this code that resembles a Caesar cipher (alphabet letter shift).

    The task is to: (All lowercase letters)

    1. Design a function, encrypt, that when applied to an unencrypted string un_str, transforms un_str to an encrypted string en_str using a right shift of length s to the letters of the alphabet with wraparound.
    2. Design a function decrypt that when applied to an encrypted string en_str, transforms en_str to a decrypted string. The string en_str will have been encrypted with a cipher of length s.

    Input: Shift length s, unencrypted string un_str, encrypted en_str
    Output: String un_str and its encryption using function encrypt, String en_str and its decryption using function decrypt

    Finished Program should be able to:

    - Prompt for and get shift length x
    - Prompt for and get unencrypted string un_str
    - Encrypt un_str into en_str
    - Prompt for and get encrypted string en_str
    - Decrypt en_str into un_str


    This is what I have so far, it's obviously amateur's work and I know there are SEVERAL errors as it is (though I'm not sure where ~). I'm trying to have it so that the program asks for a shift length, followed by offering a decrypt or encrypt option, followed by prompting for an entered string, and have the ability to perform those processes. Unfortunately I'm stuck. The string part, I really need help on. Thanks in advance

    Code:
    Title: 9.cpp
    
    
    #include "9f.h"
    #include <iostream>
    #include <stdio.h>
    #include <string>
    using namespace std;
    
    int main(void)
    {
    	char un_str[100];
    	int shift;
    	int crypt;
    
    	std::cout << "Enter a desired shift length -> "; 
    	std::cin >> shift;
    
    	std::cout << "Press 1 to encrypt or 0 to decrypt: ";
    	std::cin >> crypt;
    	while (getchar() != '\n');
    	if (crypt == 1)
    		encrypt(shift);
    	else 
    	{
    		decrypt(shift);
    	}
    		
    	std::cout << "Enter a string -> ";
    	std::cin.getline(un_str, 100);
    
    	return 0;
    }
    Code:
    Title: 9f.cpp
    
    
    #include "9f.h"
    #include <iostream>
    
    void encrypt(int shift) // prototypes of functions used in the code
    {
    	char en_str;
    	std::cout <<
    	en_str = getchar();
    	while(en_str != '\n')
    	{
    		if (ch == ' ')
    			putchar(en_str);
    		else
    		{
    			if(shift == 1)
    				putchar (en_str + shift);
    			else
    				putchar (en_str - shift);
    		}
    		en_str = getchar();
    	}
    	putchar(en_str);
    
    	return 0;
    }
    
    void decrypt(int shift)
    {
    	shift = -1 * shift;
    	encrypt(shift);
    	return 0;
    }
    Code:
    Title: 9f.h
    
    
    void encrypt (int shift);
    void decrypt (int shift);
    Reply With Quote
      #2    
    Old July 16th, 2009, 03:36 AM
    monarch_dodra's Avatar
    monarch_dodra monarch_dodra is offline
    Senior Member
     
    Join Date: Jun 2009
    Location: France
    Posts: 1,195
    monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)
    Re: Encryption Program Problem

    You are on the right track. One of your problems is the successive calls of getchar. Remember that not only does it read the last letter of your input, it also REMOVES that letter from your input.

    when you write:

    Code:
    while (getchar() != '\n');
    if the character is not \n, then it is lost forever! you are right to do the test, but you should also try not to loose that character.

    If I were you, I would modify your encrypt and decrypt functions to not require user input. Keep all the user input management inside your main. I my opinion, this is what your encrypt should look like:

    Code:
    char encrypt(char input, int shift) //Takes a char, a shift, and returns the encrypted char
    {
        char encrypted;
        encrypted= input + shift;
        if (encrypted > 122) 
        {
            encrypted -= 26;
        }
        return encrypted;
    }
    The above code assumes 0<shift<26. See http://en.wikipedia.org/wiki/ASCII#A...ble_characters for an explanation of if encrypted > 122. There is a general formula, but more complicated, for shifts > 26.

    I'm also confused about your main. You call the encrypt/decrypt functions before asking the user for a string. What is up with that? Try something like this:

    Code:
    int main(void)
    {
    	char un_str[100];
    	char en_str[100];
    	int shift;
    	int crypt;
    	char current_letter;
    
    	std::cout << "Enter a desired shift length -> "; 
    	std::cin >> shift;
    
    	std::cout << "Press 1 to encrypt or 0 to decrypt: ";
    	std::cin >> crypt;
    		
    	std::cout << "Enter a string -> ";
    	std::cin.getline(un_str, 100);
    
    	//Loop begin
    	//Validate input, ie not space etc
    	en_str[i] = encrypt(current_letter, shift);
    	//loop end
    
    	cout << en_str;
    
    	return 0;
    }
    You are on the right track. Keep going.

    If you want my personal advice, don't worry about bad user input in the beginning, as it is distracting you from thinking about the real problem. Solve the real problem, then worry about correcting user input. By the same logic, concentrate on encoding only right now. You'll worry about the if logic later.
    Reply With Quote
      #3    
    Old July 16th, 2009, 09:02 AM
    mikesnuggets22 mikesnuggets22 is offline
    Junior Member
     
    Join Date: Jul 2009
    Posts: 6
    mikesnuggets22 is an unknown quantity at this point (<10)
    Re: Encryption Program Problem

    Is there a way to do it so that a 122 and +- 26 isn't necessary? As far as that main function, yeah I'm confused, not sure where to go with the strings
    Reply With Quote
      #4    
    Old July 16th, 2009, 11:33 AM
    monarch_dodra's Avatar
    monarch_dodra monarch_dodra is offline
    Senior Member
     
    Join Date: Jun 2009
    Location: France
    Posts: 1,195
    monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)
    Re: Encryption Program Problem

    Quote:
    Originally Posted by mikesnuggets22 View Post
    Is there a way to do it so that a 122 and +- 26 isn't necessary?
    Yes, but they are much heavier code wise, and you'd have to test each letter one by one (if 'a' return 'b' etc). The idea is that a lowercase letter has a binary value between 97 and 122, included. a is 97 and z is 122. The problem is that if you try to shift the letter z, by doing z + shift, you'll have a number above 122.

    If you want to avoid the if, use this formula, it will always work.

    encrypted = ((letter - 97 + shift) % 26) + 97;

    Another solution would be doing giant switch statement, or using while loops or other. But I don't think they would be as effective.

    Here is a solution, but I wouldn't use it.

    Code:
    shift = shift%26;
    encrypt = non_encrypt;
    for (int i=0; i<shift; i++)
    {
        switch encrypt
        {
            case 'a': encrypt = 'b'; break;
            case 'b': encrypt = 'c'; break;
            case 'c': encrypt = 'd'; break;
            ...
            case 'z': encrypt = 'a'; break;
        }
    }
    This will shift your letter by 1, and you run it shift times.
    Reply With Quote
      #5    
    Old July 16th, 2009, 11:42 AM
    laserlight laserlight is offline
    Elite Member
    Power Poster
     
    Join Date: Jan 2006
    Location: Singapore
    Posts: 4,806
    laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)
    Re: Encryption Program Problem

    Quote:
    Originally Posted by monarch_dodra
    The idea is that a lowercase letter has a binary value between 97 and 122, included. a is 97 and z is 122.
    In theory, though no longer in practice as far as I know, those characters need not have those values, and need not even be contiguous in alphabetical order.

    Quote:
    Originally Posted by monarch_dodra
    If you want to avoid the if, use this formula, it will always work.

    encrypted = ((letter - 97 + shift) % 26) + 97;
    It would be somewhat more readable to write:
    Code:
    encrypted = ((letter - 'a' + shift) % 26) + 'a';
    plus it also has the theoretical benefit of working on any character set for which the lowercase letters of the English alphabet are in order and contiguous.

    Quote:
    Originally Posted by monarch_dodra
    Another solution would be doing giant switch statement, or using while loops or other. But I don't think they would be as effective.
    A switch would guarantee that it works regardless of how those characters are laid out in the character set, but then this advantage is quite theoretical.
    __________________
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful
    Reply With Quote
      #6    
    Old July 16th, 2009, 05:28 PM
    monarch_dodra's Avatar
    monarch_dodra monarch_dodra is offline
    Senior Member
     
    Join Date: Jun 2009
    Location: France
    Posts: 1,195
    monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)
    Re: Encryption Program Problem

    Quote:
    Originally Posted by laserlight View Post
    In theory, though no longer in practice as far as I know, those characters need not have those values, and need not even be contiguous in alphabetical order.
    While I understand character mapping is environment dependent, I was pretty sure all modern OS followed the ASCII scheme for at least the first 127 symbols, and the rest locale dependent. What do you mean: "no longer in practice"? Do you just mean that there is no guarantee they follow this scheme?

    Quote:
    Originally Posted by laserlight View Post
    It would be somewhat more readable to write:
    Code:
    encrypted = ((letter - 'a' + shift) % 26) + 'a';
    plus it also has the theoretical benefit of working on any character set for which the lowercase letters of the English alphabet are in order and contiguous.
    Agree with you 100%. I just think it is easier to explain a formula with numbers, and afterwards easier to read with characters (and a bit more portable).

    Quote:
    Originally Posted by laserlight View Post
    A switch would guarantee that it works regardless of how those characters are laid out in the character set, but then this advantage is quite theoretical.
    Agree too, but I didn't want to bring in portability, as this was just a simple homework assignment.
    Reply With Quote
      #7    
    Old July 16th, 2009, 06:31 PM
    mikesnuggets22 mikesnuggets22 is offline
    Junior Member
     
    Join Date: Jul 2009
    Posts: 6
    mikesnuggets22 is an unknown quantity at this point (<10)
    Re: Encryption Program Problem

    thanks, I'm updating my program now and hopefully it works. in the meantime, I've learned that this is a skeleton of what it's supposed to look like:

    You need to be writing a global function to get the shift and another to get the string.

    Code:
    int main()
    {
            // Get shift
            int shift = get_shift();
    
            // Get input string
            std::string input = get_string();
    
            // Encrypt.  Save the original string
            std::string encrypted;
            encrypt(input, encrypted);
    
            // Display results
            display(input, encrypted);
    
    ......... get_string, decrypt, and display
    
            return 0;
    }
    Still thinking about how to do the strings unless it's that simple



    Also I'm getting errors from this:

    //Loop begin
    //Validate input, ie not space etc
    en_str[i] = encrypt(current_letter, shift);
    //loop end

    pa4.cpp:34: error: `i' was not declared in this scope
    pa4.cpp:34: error: invalid conversion from `char' to `char*'
    pa4.cpp:34: error: initializing argument 1 of `void encrypt(char*, int)'

    Last edited by mikesnuggets22; July 16th, 2009 at 06:44 PM.
    Reply With Quote
      #8    
    Old July 17th, 2009, 04:44 AM
    monarch_dodra's Avatar
    monarch_dodra monarch_dodra is offline
    Senior Member
     
    Join Date: Jun 2009
    Location: France
    Posts: 1,195
    monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)monarch_dodra is a jewel in the rough (200+)
    Re: Encryption Program Problem

    Quote:
    Originally Posted by mikesnuggets22 View Post
    thanks, I'm updating my program now and hopefully it works. in the meantime, I've learned that this is a skeleton of what it's supposed to look like:

    You need to be writing a global function to get the shift and another to get the string.

    Code:
    int main()
    {
            // Get shift
            int shift = get_shift();
    
            // Get input string
            std::string input = get_string();
    
            // Encrypt.  Save the original string
            std::string encrypted;
            encrypt(input, encrypted);
    
            // Display results
            display(input, encrypted);
    
    ......... get_string, decrypt, and display
    
            return 0;
    }
    Still thinking about how to do the strings unless it's that simple
    yes, this looks much better. Now, you need to implement your functions. It shouldn't be too hard, you already written the code required by get_string in your main. display is basically just cout << input << " " << encrypted << cout.


    Quote:
    Originally Posted by mikesnuggets22 View Post
    Also I'm getting errors from this:

    //Loop begin
    //Validate input, ie not space etc
    en_str[i] = encrypt(current_letter, shift);
    //loop end

    pa4.cpp:34: error: `i' was not declared in this scope
    pa4.cpp:34: error: invalid conversion from `char' to `char*'
    pa4.cpp:34: error: initializing argument 1 of `void encrypt(char*, int)'
    That's because it was not literal code, and I didn't write the loop. If you choose to not encrypt non-lowercase lettes, you can just do a for(int i=0; i != your_string.size(); ++i). As for the char*/char errors, it is up to you to decide if you want to work on letters at once, or on the entire string.
    Reply With Quote
      #9    
    Old July 17th, 2009, 05:56 AM
    laserlight laserlight is offline
    Elite Member
    Power Poster
     
    Join Date: Jan 2006
    Location: Singapore
    Posts: 4,806
    laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)laserlight has much to be proud of (1500+)
    Re: Encryption Program Problem

    Quote:
    Originally Posted by monarch_dodra
    While I understand character mapping is environment dependent, I was pretty sure all modern OS followed the ASCII scheme for at least the first 127 symbols, and the rest locale dependent. What do you mean: "no longer in practice"? Do you just mean that there is no guarantee they follow this scheme?
    Yes, there is no guarantee.
    __________________
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 09:04 PM.



    Acceptable Use Policy

    Internet.com
    The Network for Technology Professionals

    Search:

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.