退出循环时字符串的内容发生变化

时间:2010-08-20 15:45:11

标签: c++ for-loop xor

我有一个简单的函数,它检查给定的字符串是否匹配某个条件,然后根据作为参数接收的2个字符串生成第3个字符串。第三个字符串很好但是当我返回时它会突然变成“\n”。

string sReturn = "";
if (sText.size() != sPassword.size()) {
     //Checks to see if the texts match a condition
     return sReturn;
}
for (int foo = 0; foo < sText.size(); foo++) {
    sReturn = "";
    sReturn += (char)sText[foo] ^ (char)sPassword[foo];
}
return sReturn;

for sReturn很好并且内容正确,但只要它存在循环,调试器突然告诉我它的内容是“\n”。我做错了什么?

4 个答案:

答案 0 :(得分:3)

为什么在循环中有sReturn = "" 。不应该在循环之前初始化吗?

在给定的情况下,sReturn只会有一个字符。在你的情况下,我会假设^操作在最后一次迭代中产生一个\ n字符。

答案 1 :(得分:3)

  1. 您不必初始化字符串 空字符数组如:

    std::string sReturn = "";
    

    Default constructor意味着这样做 为你而且效率更高。 正确的代码:

    std::string sReturn;
    
  2. 为sReturn分配一个空字符串 在循环中的每次迭代中 不正确。更不用说了 清除你必须打电话的字符串 std::string::clear ()

    sReturn = "";
    

    正确的代码:

    sReturn.clear (); 
    

    但这应该从中移除 在你的情况下循环。

  3. 无需明确说明 转换运算符[]的结果 (size_t)因为它而成为一个角色 是一个角色:

    sReturn += (char)sText[foo] ^ (char)sPassword[foo];
    

    正确的代码:

    sReturn += sText[foo] ^ sPassword[foo];
    
  4. 使用post-increment代替 循环是没有必要的。它成了一个 每个人都有额外的“foo”副本 增量:

    for (int foo = 0; foo < sText.size(); foo++)
    

    这可能会优化 编译器,但你必须摆脱 这个坏习惯。使用 而是pre-increment。正确 代码:

    for (int foo = 0; foo < sText.size(); ++foo)
    
  5. 调用std :: string :: size() 字符串大小时的每次迭代 不变不高效:

    for (size_t foo = 0; foo < sText.size(); ++foo)
    

    更好的代码:

    for (size_t foo = 0, end_foo = sText.size(); foo < end_foo; ++foo)
    

    注意size_t类型。你不能存储 字符串大小,以32位有符号整数表示 因为它没有足够的容量 存储大量。正确的类型是 size_t,由...返回 std :: string :: size()方法。

  6. 考虑到上述所有因素,正确的功能应如下所示:

    std::string
    getMixedString (const std::string & text, const std::string & password)
    {
        std::string result;
        if (text.length () != password.length ())
            return result;
        for (size_t pos = 0, npos = text.length (); pos < npos; ++pos)
            result += text[pos] ^ password[pos];
        return result;
    }
    

    但如果您希望最终字符串是人类可读的,则会出现问题。在两个eXclusive OR字符上使用ASCII(XOR)运算符可能会也可能不会为您提供人类可读的字符,甚至是ASCII字符。因此,您最终可能会得到包含换行符,不可读字符,一些garbage的结果字符串。

    要解决这个问题,你必须提出一些更好的算法来生成基于另外两个字符串的字符串。例如,您可以使用MD5两个字符串的哈希值,或者在base64中对其进行编码。

    祝你好运!

答案 2 :(得分:2)

你已经解决了这个问题。我会建议一种完全不同的做事方式,我认为这样可以消除产生类似错误的可能性。首先,我将“编码”部分中的“检查文本是否与条件匹配”部分分开。现在,你有一个(相当小的)代码似乎有两个,主要是无关的责任。

编码部分,我写的是这样的:

struct encode_byte { 
    char operator()(char a, char b) { 
        return a ^ b;
    }
};

std::transform(sText.begin(), sText.end(),
               sPassword.begin(), sPassword.end(),
               std::back_inserter(sResult),
               encode_byte());

答案 3 :(得分:2)

string sReturn;
if (sText.size() != sPassword.size()) {
        return sReturn;
}
for (size_t foo = 0, end_foo = sText.size(); foo < end_foo; ++foo) {
        sReturn += sText[foo] ^ sPassword[foo];
}
return sReturn;

我现在用大家的提示改写了它。我为缺乏注意力造成的错误道歉 - 每次我在循环中运行时清除字符串。我希望现在好了,请告诉我是否有任何问题。感谢大家的快速回答。