在C ++ 11中对字符串进行异或

时间:2018-01-12 09:11:38

标签: c++ string c++11

我正在尝试在C ++ 11(Visual Studio 2017)中对字符串实现简单的XOR编码。但是,我在实现它时遇到了一些问题。以下代码将是我的标准(C)方法:

char* encode(char*  input) {
   for (unsigned int i = 0; i < strlen(input); i++) {
        input[i] ^= 0xA; 
   }
   return(input);
 }

 int main(void){
   printf(encode(encode("Hello World!")));
 }

但它不是有效的代码,因为字符串(“Hello Wolrd!”)的类型为const char*.

我尝试了几件事来解决这个问题:

  1. 将字符串转换为(char*)(即encode( (char*)"Hello World!")) 但在尝试对第一个字节进行异或时抛出异常。

  2. 在我的编码功能中使用临时char*,这也导致了。{ 堆栈腐败。

    char* encode(const char*  input) {
      char temp[128];
      strncpy(temp, input, 128);
      for (unsigned int i = 0; i < strlen(temp); i++) {
        temp[i] ^= 0xA;
      }
      return(temp);
     }  
    
  3. 我尝试使用std:string但它也没有用完。

    const char* encode(const char*  input) {  
      std::string temp(input);  
      for (char& c : temp) {
        c  ^= 0xA;
      }
      return(temp.c_str());
    }
    
  4. 我错过了什么?

2 个答案:

答案 0 :(得分:3)

只需在功能签名中使用std::string,然后完全对std::string进行操作。没有涉及C字符串。

#include <string>
#include <iostream>

std::string encode(std::string input)
{
    for (char& c : input) {
        c  ^= 0xA;
    }
    return input;
}

int main()
{
    std::cout << encode(encode("Hello World!"));
}

我建议不要使用C-string,因为它会以这些方式使事情变得复杂:

  • 字符串文字("Hello World")是只读的。你不能修改它。
  • 如果使用本地字符数组(char[SIZE]),则无法将其从函数中返回。你可以做的唯一一件事就是将一个悬空指针返回到本地数组。
  • 如果动态分配字符数组(mallocnew[]),则必须手动管理分配的内存,这很笨拙。

std::string会自动为您管理所有内容。只需使用它。

答案 1 :(得分:-1)

Jarod的回答是这样做的最佳方式之一。只是不传递常数。或者您需要创建新存储。你不能使用局部变量。主要问题是......这是纯粹的C代码。

在C ++中你写的是这样的东西:

#include <string>
#include <algorithm>
#include <iostream>

template<class T> T encode (const T& s)
{
    using CharT = typename T::value_type;
    T temp;
    for (const CharT& i : s)
    {
        temp += i ^ (CharT)0x0A;
    }
    return temp;
}

template<class T> T encode (T& s)
{
    using CharT = typename T::value_type;
    for (CharT& i : s)
    {
        i = i ^ (CharT)0x0A;
    }
    return s;
}

int main()
{
    using namespace std;
    string str("hello");

    cout << encode(str) << endl;
    cout << encode(string("Hello"))<< endl;
    cout << encode(encode(string("Hello")));
}

一个重载函数重用提供的存储,另一个创建一个时间。内存管理是自动的,仅限于std::string,模板的使用允许用于具有不同字符类型的字符串或用于与std::string具有相同语义的类。当然,static_assert可用于限制不同类型的使用或专门化模板。