0

I am making a cypher code and when I am trying to execute it I get the "std::logic_error' what(): basic_string::_M_construct null not valid". what is wrong with the code.

#include <iostream>
using namespace std;
string cipher(int key,string text);
string decipher(int key,string text);

int main(int argc, char** argv) {
   string type;
   string text;
   string dtext;
   char* key1;
   int key;
   string s = argv[1];

   if (argc != 2) {
       cout << "Usage ./ceaser key" << endl;
       return 1;
   }

   else {
        for (int k = 0;k < s.length(); k++) {

           if (isalpha(argv[1][k]))
           {
               cout << "Usage: ./caesar key" << endl;
               return 1;
           }
           else
           {
               continue;
           }
       }

   }
   cout << "Type c for cipher and d for decipher: ";
   cin >> type;
   cout << "text: ";
   getline(cin, text);

   key1 = argv[1];
   key = atoi(key1);
   if (type == "c") {
      cipher(key,text);
   }
   else {
       decipher(key,text);
   }
   cout << endl;


}

string cipher(int key,string text) {
     for (int i = 0; i < text.length(); i++) {
        if (islower(text[i])) {
            char m = (((text[i] + key) - 97) % 26) + 97;
            cout << m;
        }
        else if(isupper(text[i])){
            char a = (((text[i] + key) - 65) % 26) + 65;
            cout << a;
        } 

        else {
            cout << text[i];
        }
    }
    return 0;
}

string decipher(int key,string text) {
    for (int i = 0; i < text.length(); i++) {
         if (islower(text[i])) {
            char m = (((text[i] - key) - 97) % 26) + 97;
            cout << m;
        }
        else if(isupper(text[i])){
             char a = (((text[i] - key) - 65) % 26) + 65;
             cout << a;
        }

        else {
           cout << text[i];
        }
    }
    return 0;
}

How can I fix this, it worked fine when I only made it a cypher but not decipher. but when I try to decipher it stopped working.

  • 1
    Be a good idea to move the `if (argc != 2)` block ahead of `string s = argv[1];`. Really suck if the program failed on the line before the check to make sure it doesn't fail. – user4581301 Jun 26 '21 at 07:09
  • 1
    Side note: prefer `'a'` to `97`. The purpose of `'a'` is immediately obvious to readers and the code ha s a better chance of porting to other encodings. – user4581301 Jun 26 '21 at 07:18
  • Pretty sure the problem is [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction), but I can't prove it at the moment – user4581301 Jun 26 '21 at 07:30
  • OK, The above's not the problem, but it is a problem. – user4581301 Jun 26 '21 at 07:40

1 Answers1

2
string cipher(int key,string text) {
    ...
    return 0;
}

a return statement applies the appropriate constructor of the return type, if the returned value is not of the correct type. In this case std::string::string(const char*) is used and the null pointer is passed causing the issue. You need to return the result of the encryption here instead of printing the result to stdout. (Proceed accordingly in decypher.)

In this case contrary to my comment you may actually pass the value by copy to be able to modify the string and return it:

...
if (islower(text[i])) {
    //char m = (((text[i] + key) - 97) % 26) + 97;
    //cout << m;
    text[i] = (((text[i] + key) - 97) % 26) + 97;
}

...
return text;

fabian
  • 80,457
  • 12
  • 86
  • 114
  • Smurf. Totally missed that. I'm going to bed. The brain's clearly switched off. – user4581301 Jun 26 '21 at 07:40
  • It worked there r no errors but I am not able to give the text input which needs to deciphered or cyphered I will try to figure that out. thank you for your help – srikar amirneni Jun 26 '21 at 08:36