Removing individual characters from a string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//Vigenere cipher program
#include <iostream>
using namespace std;


void begde();
void begen();
string decrypt(string s, string code);
string encrypt(string t, string code);

int main()
{
    cout << "\t\tVigenere's Cipher Encoder/Decoder\n\
            1. Encrypt\n\
            2. Decrypt\n\
            3. Exit\n"
    int choose;
    cin >> choose;
    switch(choose)
    {
    case 1:
         begen();
         break;
    case 2:
         begde();
         break;
    default:
         return 0;
    }
}
void begen()
{
     cout << "Text to encode: ";
     string tov;
     getline(cin, tov);
     cin.get();
     cout << "Code word: ";
     string c;
     getline(cin, c);
     cout << "The encoded string is: " << encrypt(tov, c);
     cin.get();
     exit(0);
}
void begde()
{
     cout << "Text to encode: ";
     string frv;
     getline(cin, frv);
     cin.get();
     cout << "Code word: ";
     string c;
     getline(cin, c);
     cout << "The encoded string is: " << decrypt(fr, c);
     cin.get();
     exit(0);
}
string decrypt(string s, string code)
{
       string mod_s;
       for(int i = 0; i < ( sizeof (s) ); i += ( sizeof(code) ){ //to set the modified 's' string to repeated code word
               mod_s += code;
       while( sizeof(mod_s) > sizeof(s) )
       {
      //stuck here 

I wanted to know if there was a way to remove single characters from a string.
Is there?
You can use an iterator to move through the string elements and then the erase() method of the string to erase the letters you want.
For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
using namespace std;

int main(){
   string str = "What ever here";
   char remove = 'e';
   for(string::iterator it = str.begin(); it!=str.end();){
      if( (*it) == remove )
         it = str.erase( it );
      else
         it++;
   }
   cout << str << endl;
   return 0;
}


Hope this helps
Last edited on
The reference documentation here really is top-notch. Check it out
http://www.cplusplus.com/reference/string/string/erase.html
So to erase the extra, I'll try:
mod_s.erase(sizeof(s), code);
More needed. I found that the only way I knew of to do this was by using char arrays, but the functions don't match up and all.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <string>
using namespace std;


void begde();
void begen();
string encrypt(char s[], int n, string code);
string decrypt(char t[], int n, string code);

int main()
{
    cout << "\t\tVigenere's Cipher Encoder/Decoder\n\
            created by QWERTYman (c) 2008\n\
            1. Encrypt\n\
            2. Decrypt\n\
            3. Exit\n";
    int choose;
    cin >> choose;
    switch(choose)
    {
    case 1:
         begen();
         break;
    case 2:
         begde();
         break;
    default:
         return 0;
    }
}
void begen()
{
     cout << "Text to encode (all caps, please): ";
     char tov[500];
     for(int i = 0; i < 500; i++)
     tov[i] = '\0';
     cin.getline(tov, 500);
     cin.get();
     cout << "Code word: ";
     string c;
     getline(cin, c);
     cout << "The encoded string is: " << encrypt(tov, 500, c);
     cin.get();
     exit(0);
}

string encrypt(char s[], int n, string code)
{
       const int t = sizeof(s);
       char mod_s[t];
       for(int i = 0; i < ( sizeof(s) ); i += ( sizeof(code) )){ //to set the modified 's' string to repeated code word
              mod_s = mod_s + code;
       mod_s.erase(t, sizeof(code));//erases extra letters
       char encoded[500];
       if( !mod_s.find(' ') && !mod_s.find('\n') )
       for(int i = 0; i < sizeof(s); i++)
       encoded[i] = ( mod_s[i] + (int(s[i]) - 65) );
       return encoded;
}

Help!
Last edited on
The erase needs an iterator or a start and a stop position using iterators or size_type values.
If you use mod_s.erase(sizeof(s), code); then the second variable is a string, which is illegal.

You are trying to find a keyword in the main string and erase it?

[EDIT] I was writing and didn't notice your post
Last edited on
I modified that problem in the above post.
The find() method returns -1 if it doesn't find anything.
So your statement if( !mod_s.find(' ') && !mod_s.find('\n') ) means:
if it finds in position 0 (the first letter of the string) a space and a new line.

I think that you mean if it doesn't find it, so compare the find with -1
if( (mod_s.find(' ')==-1) && (mod_s.find('\n')==-1) )
Last edited on
Are there methods of erasure or assignment for use with chars? Need help with lines 53-54.

Thx.
I don't really undeerstand what you are trying to do but if you have an array and you want to erase some elements then you can either make a new array that has all the elements of the original except the ones you want to delete or move all the elements after the ones you want to delete the necessary positions to replace the ones.
Last edited on
One more thing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <string>
using namespace std;


void begde();
void begen();
string encrypt(char s[], int n, string code, int m);
string decrypt(char t[], int n, string code, int m);

int main()
{
    cout << "\t\tVigenere's Cipher Encoder/Decoder\n\
            created by QWERTYman (c) 2008\n\
            1. Encrypt\n\
            2. Decrypt\n\
            3. Exit\n";
    int choose;
    cin >> choose;
    switch(choose)
    {
    case 1:
         begen();
         break;
    case 2:
         begde();
         break;
    default:
         return 0;
    }
}
void begen()
{
     cout << "Text to encode (all caps, please): ";
     char tov[500];
     for(int i = 0; i < 500; i++)
     tov[i] = '\0';
     cin.getline(tov, 500);
     cin.get();
     cout << "Code word: ";
     char c[500];
     for(int i = 0; i < 500; i++)
     c[i] = '\0';
     cin.getline(c, 500);
     cout << "The encoded string is: " << encrypt(tov, 500, c, 500);
     cin.get();
     exit(0);
}

string encrypt(char s[], int n, char code[], int m)
{
       const int t = sizeof(s);
       
       char mod_s;
       for(int i = 0; i < ( sizeof(s) ); i += ( sizeof(code) )){ //to set the modified 's' string to repeated code word
       for(int j = 0; j < sizeof(code); j++){
       int u = sizeof(mod_s) + 1;
       mod_s[u] = code[j];}}
       
       for(int i = ( sizeof(mod_s) - sizeof(s) ); i < sizeof(mod_s); i++)
       mod_s[i] = '\0';//erases extra letters
       char encoded[500];
       for(int i = 0; i < sizeof(mod_s); i++){
       if(mod_s[i] == ' ' || mod_s[i] == '\n')
       for(int j = 0; j < sizeof(s); j++)
       encoded[j] = ( mod_s[j] + (int(s[j]) - 65) );}
       return encoded;
}

In function `std::string encrypt(char*, int, char*, int)':
error: invalid types `char[int]' for array subscript
error: invalid types `char[int]' for array subscript
error: invalid types `char[int]' for array subscript
error: invalid types `char[int]' for array subscript
error: invalid types `char[int]' for array subscript

...What?
Woah! I missed that.
sizeof will not give you what you want. Use s.length() to get the number of characters in a std::string.

You can truncate a string with erase()

mod_s.erase( s.length() ); // makes s and mod_s the same length

But you really don't need to do that. You can use some STL magic to help you along instead
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <algorithm>   // fill_n() and transform()
#include <functional>  // minus<> and plus<>
#include <iterator>    // ostream_iterator<>
#include <sstream>
#include <string>
...
string decrypt( string s, string code )
  {
  // Copy the 'code' string sufficient to match the cipher string's length
  ostringstream mod_s;
  fill_n(
    ostream_iterator <string> ( mod_s ),
    (s.length() /code.length()) +1,
    code
    );

  // cipher - keycode = plaintext
  transform(
    s.begin(),
    s.end(),
    mod_s.str().begin(),
    s.begin(),
    minus <char> ()
    );

  return s;
  }

In this example, of course, I assumed E() = p + k and D() = c - k. If you've done it the other way around you'll have to fix that. You'll notice that it doesn't matter if mod_s is actually longer than s, since the transformation stops at the end of s anyway...

[edit] wow, go and change the laundry before hitting 'submit'... :-\
Last edited on
Line 54. You have char mod_s; but you try to access it as an array. You probably mean string mod_s; or
char mod_s[someSize];
Last edited on
WORKS!
Now, I am having some trouble using getline, so I might change it to cin.get().
Last edited on
My guess: You probably tryed to access an off-limits memory address...
Nope, just a typo.
It doesn't show the encoded version of the string, but it should.
Help!
Topic archived. No new replies allowed.