3

I have tried to make basic string encryption, by swapping two consecutive letters. And it didn't really work as I intended.

#include <iostream>
#include <string.h>
#include <algorithm>

int main() 
{
    std::string str = "This is a simple string.";
    for (int i = 0; i <= str.length(); i++) {
        std::swap(str[i], str[i + 1]);
    }
    std::cout << str;
    std::cin.get();
}

I want to actually swap two near letters, so it will look like encrypted. The Current result is

his is a simple string.
JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 2
    Undefined behavior, due to indexing past the end of the `str` (when `i == str.length ()`, and `i == str.length () - 1`). – Algirdas Preidžius Jun 09 '19 at 17:45
  • 3
    This: " for (int i = 0; i <= (str.length()-2); i++) " results in output "his is a simple string.T". Understand swap better? (It is not a good encryption.) – 2785528 Jun 09 '19 at 17:48
  • Also, the correct header for `std::string` is ``, not ``. – PaulMcKenzie Jun 09 '19 at 17:58
  • 3
    To be more precise, here are the [dangers of using the incorrect string header](https://rextester.com/SUJ69640). Your program fails to compile in Visual Studio. – PaulMcKenzie Jun 09 '19 at 18:04

2 Answers2

5

First of all, you have out of bound access because of

for (int i = 0; i <= str.length(); i++) 
//                ^^^^

hence the behavior of your program is undefined. You want to iterate one past the size of the string. In addition to that, loop only if the string is not empty(credits @jww).

Secondly, there is a comparison between int and unsigend int(i.e. str.length()) which is also not you want.

Last but not least, add the proper header for std::string(as @PaulMcKenzie pointed out in the comments).

Altogether, you probably want this

#include <string>

for (std::size_t i = 0; !str.empty() && i < str.size()-1; i += 2) {
//   ^^^^^^^^^^^        ^^^^^^^^^^^^        ^^^^^^^^^^^^   ^^^^^
    std::swap(str[i], str[i + 1]);
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
4

I think you were aiming for something like:

std::string str = "This is a simple string.";
for (int i = 0; i <= str.length()-2; i+=2) 
{
    std::swap(str[i], str[i + 1]);
}
std::cout << str;

with output

hTsii  s aispmels rtni.g
2785528
  • 5,438
  • 2
  • 18
  • 20
  • 3
    Maybe something like `for (size_t i = 0; !str.empty() && i < str.length() - 1; i++)` to handle empty messages, too. – jww Jun 09 '19 at 18:37
  • Yes ... my code offering has UB when "str.size() < 2" ... I leave it for the OP – 2785528 Jun 11 '19 at 20:26