Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Homework Help: Decoding fail

  1. Jul 28, 2010 #1
    i am trying to write a program that encodes and decodes. my code works fine for encoding 1 string of characters with no spaces, but when there is any type of white space, it fails. also, when i try to decode, i get a random mix of characters and symbols. any help would be appreciated.

    for example (using the keyword lemon)
    input text file: attackatdawn
    output text file (encode): lxfopvefrnhr // success!!

    input text file: attack at dawn
    output text file (encode): lxfopvXmhaoeib // FAIL...the spaces should merely show up as spaces

    input text file: lxfopvefrnhr
    output text file (decode): aÂ#„åF§iÊ+Œí // FAIL...idk what this is

    Code (Text):

    void perform(istream& inf, ostream& outf, string key, char choice)
    {
        string text;
        while(getline(inf, text))
            {
            for (int i = 0; i < text.length(); i++)
            {
                if (key.length() <= text.length())
                    key += key[i];
            }
            // encode
            if (choice == 'e')
            {
                for (int j = 0; j < key.length(); j++)
                {
                    key[j] = tolower(key[j]);
                    alpha_to_num(key[j]);
                }
                for (int k = 0; k < text.length(); k++)
                {
                    text[k]= tolower(text[k]);
                    alpha_to_num(text[k]);
                }
                for (int l = 0; l < text.length(); l++)
                {
                    eForm(c, text[l], key[l]);
                    num_to_alpha(c);
                    outf << (char)c;
                }
            }
            // decode
            else if (choice == 'd')
            {
                for (int j = 0; j < key.length(); j++)
                {  
                    key[j] = tolower(key[j]);
                    alpha_to_num(key[j]);
                }
                for (int k = 0; k < text.length(); k++)
                {
                    text[k]= tolower(text[k]);
                    alpha_to_num(text[k]);
                }
                for (int l = 0; l < text.length(); l++)
                {
                    dForm(c, text[l], key[l]);
                    num_to_alpha(c);
                    outf << (char)c;
                }
            }
        }
    }

    int main(){
        char choice;
        string key;
        string input;
        string output;
        ifstream inf;
        ofstream outf;
         
            cin >> choice >> key >> input >> output;
        inf.open(input.c_str());
        outf.open(output.c_str());

        perform(inf, outf, key, choice);
    }
     
     
  2. jcsd
  3. Jul 28, 2010 #2

    Mark44

    Staff: Mentor

    If you want spaces in plain text to show up as spaces in the encrypted text, you will need some logic in the encryption part of your code that doesn't encrypt spaces (and maybe other kinds of whitespace such as tabs and/or newline characters.

    You should have in mind what your code will produce when it encrypts or decrypts a string. By that, I mean you should be spending more time on your algorithm and less time entering your code. If the plain text is "attack at dawn" and the key is "lemon" you should know before you run your program what the output should be, and should compare your actual output with what you are designing your program to do. The debugger is your friend - get to know how to use it to single step through your code.
     
  4. Jul 28, 2010 #3
    http://www.daniweb.com/forums/thread257218.html" [Broken]
     
    Last edited by a moderator: May 4, 2017
  5. Jul 28, 2010 #4
    i just discovered the debugger. i have a breakpoint in my code starting at the decoding part, but how do i step through it?
     
  6. Jul 29, 2010 #5

    Mark44

    Staff: Mentor

    It probably depends on what debugger you're using. There should be some documentation or help or something for the debugger, and the docs would say how to single-step through your code.
     
  7. Jul 30, 2010 #6
    i have run my debugger and it seems to show that an entire loop is not being iterated through. below is my modified code (not yet sure if the algorithm is correct). everything inside the while(inf.get(text)) does not get executed. any thoughts on why this is so?

    Code (Text):

    int findTextSize(istream& inf)
    {
        char text;
        int textSize = 0;
        while(inf.get(text))
        {
            textSize++;
        }
        return textSize;
    }

    // process the text from the file and do the actual encoding
    void perform(istream& inf, ostream& outf, string& key, string choice)
    {
        int textSize = findTextSize(inf);
        char text;
        for (int y = 0; y < textSize; y++)
        {
            if(key.size() <= textSize)
                key += key[y];
        }
        int inputIndex = 0;
        int keyIndex = 0;
        int i = 0;
        string alphabet = "abcdefghijklmnopqrstuvwxyz";
        while(inf.get(text))
        {
            if (!isalpha(text))
                outf << text;
            else
            {
                if (isalpha(text))
                    text = tolower(text);
                for (int j = 0; j < alphabet.length(); j++)
                {
                    if (text == alphabet[j])
                        inputIndex = j;
                    if (key[j] == alphabet[j])
                        keyIndex = j;
                }
                if (choice == "e")
                    outf << alphabet[(inputIndex - keyIndex) % 26];
                else if (choice == "d")
                    outf << alphabet[(26 - inputIndex + keyIndex) % 26];
            }
            i++;
            i = i % key.length();
        }
    }
     
     
  8. Jul 31, 2010 #7
    I'm not familiar with c++, but I found this http://www.cplusplus.com/reference/iostream/istream/get/

    Code (Text):

    // istream get
    #include <iostream>
    #include <fstream>
    using namespace std;

    int main () {
      char c, str[256];
      ifstream is;

      cout << "Enter the name of an existing text file: ";
      cin.get (str,256);

      is.open (str);        // open file

      while (is.good())     // loop while extraction from file is possible
      {
        c = is.get();       // get character from file
        if (is.good())
          cout << c;
      }

      is.close();           // close file

      return 0;
    }
    So from my guess, I would think you're not suppose to have anything in inf.get().

    If that doesn't fix your problem, can you write in English what you want to do?
     
    Last edited by a moderator: Apr 25, 2017
  9. Aug 1, 2010 #8

    Mark44

    Staff: Mentor

    The get method of istream has six overloads, one of which takes a reference to a char. See http://www.cplusplus.com/reference/iostream/istream/get/ for descriptions of these methods.

    In your call to get you have
    Code (Text):
    while(inf.get(text))
    I think this is what you should be doing:
    Code (Text):
    while(text = inf.get())
    Also, as a minor point, you have
    Code (Text):

    while(inf.get(text))
    {
       if (!isalpha(text))
          outf << text;
       else
       {
          if (isalpha(text))
          ...
       }
     
    There is no need for the first line in your else clause, if (isalpha(text)). To get to that point in your code, isalpha(text) must already have returned true (or rather, 1), so you don't need to test for it again with an if statement.

    As for your algorithm, it needs some work. You shouldn't be testing to determine the value of choice for each character you decrypt or encrypt. You should do that once, not for each iteration of your while loop.

    After you have determined that choice == 'e' or choice == 'd', you should carry out the operation that is needed.

    BTW, you have define choice as a string, which is probably not the right thing to do. Since it holds only a single character (I think), it should be declared as char, not string. That brings me to an error you have by declaring choice as a string. This line,
    Code (Text):
    if (choice == "e")
    does not do what you think it will do, with choice declared as a string. Instead of evaluating to true if choice contains the letter e, it evaluates to true if the address of choice is the same as the address of the string "e". That's definitely NOT what you want. You cannot compare the contents of two strings using == in C or C++.

    Finally, you should get into the habit of inserting comments in your code. There is only one comment in the last code you provided. Notice the comments in the code that sourlemon provided. Not only do comments help other readers understand what your code is trying to do, but they help you remember why you are trying to do something. Start from an algorithm in pseudocode, and then lay out your C++ code, with comments for each step you had in your pseudocode.
     
    Last edited by a moderator: Apr 25, 2017
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook