用'%20'替换字符串中的所有空格(C ++)

时间:2016-07-13 22:36:25

标签: c++ string memory-management str-replace

在理解部分代码时遇到一些麻烦;我得到的输出也是错误的。问题是用'%20'替换字符串中的所有空格。完整代码如下所示;它编译但不完全按预期运行。

#include <iostream>
#include <string>
using namespace std;

void replaceSpaces(string str){

    //Getting the length of the string, counting the number of spaces 
    int strLen = str.length();
    int i, count = 0;
    for (i = 0; i <= strLen; i++) {
        if(str[i]==' ')
        count++;
    }

    //Determining the new length needed to allocate for replacement characters '%20'
    int newLength = strLen + count * 2;

    str[newLength] = '\0';
    for (i = strLen - 1; i >= 0; i--) {
        if (str[i] == ' ') {
            str[newLength - 1] = '0';
            str[newLength - 2] = '2';
            str[newLength - 3] = '%';
            newLength = newLength - 3;
        }

        else {
            str[newLength - 1] = str[i];
            newLength = newLength -1;
        }
    }
    cout << str <<endl;

}

int main() {

    string str = "hello jellybean hello";
    replaceSpaces(str);

    return 0;

}

我可能遗漏了一些明显的东西,但是当在这一行中分配新的字符串长度时:

int newLength = strLen + count * 2;

这里我们将空格数乘以2,但如果我们尝试用&#39;%20&#39;替换所有空格,为什么不将它乘以3呢?

str[newLength] = '\0';

这一行是否表示超出字符串中最后一个字符的位置被赋予空格?

我也对else声明感到困惑。

 else {
        str[newLength - 1] = str[i];
        newLength = newLength -1;
    }

不确定我是否完全理解执行此操作时的情况。

编译并运行函数时,如果

string str = "hello jellybean hello";

预期输出为 hello%20jellybean%20hello ,但我得到的输出是 hello%20jellybean%20h

就时间复杂度而言,由于有两个独立的for循环,时间复杂度是 O(n)吗?

我知道我提出了很多不同的问题,非常感谢您提出任何答案!

5 个答案:

答案 0 :(得分:2)

这是错误的:

str[newLength] = '\0';

std::string个对象根据其大小在内部维护其NUL终止符。你想要

str.resize(newLength);

代替。

答案 1 :(得分:1)

 int a = 221;
 unsigned char buffer[10] = {0};
 buffer[0] = a;

表示分配空间(稍后),等于字符串的长度,再加上发现的空格数乘以2,这是有道理的。

例如:int newLength = strLen + count * 2; ,应该使用空格为so glad to help生成的插槽,并且每个插槽需要两个以上的插槽,用于替换的%部分发挥作用。

这是错误

20
你看不到吗?您可以从字符串的边界访问内存。你的行为就像你实际分配的空间等于str[newLength] = '\0'; ,但你还没有在代码中的任何地方。

未定义的行为中访问结果的界限越来越严重。

else语句只是用于复制非空格字符,但你应该已经放弃了该代码(如果它不是你的代码)并从头开始或/并在:{{3 }}

至于错误的结果,你应该知道达到答案的那一点,这是预期的。

答案 2 :(得分:0)

尝试进行修改非常棘手。创建新字符串要容易得多:

std::string new_string;
for (int i = 0; i < str.length(); ++i) {
    if (str[i] == ' ')
        new_string += "%20";
    else
        new_string += str[i];
}
return new_string;

或者,如果你喜欢range-for:

std::string new_string;
for (char ch : str) {
    if (ch == ' ')
        new_string += "%20";
    else
        new_string += ch;
}
return new_string;

答案 3 :(得分:0)

您可以在函数中更改该字符串参数以引用,然后不需要新的字符串,在代码的其他部分,您可以使用插入函数来添加&#39; 2&#39;和&#39; 0&#39;,您只需将空格转换为&#39;&amp;&#39;。

void replaceSpaces(string &str) {
        size_t strLen = str.length();
        for (int i = 0; i < strLen; i++) {
            if (str[i] == ' ') {
                str[i] = '%';
                str.insert(str.begin() + i + 1, '2');
                str.insert(str.begin() + i + 2, '0');
                strLen += 2;
            }
        }
    }

答案 4 :(得分:0)

这很容易;将examplestring替换为代码中的字符串,并按照以下方式使用:

#include <iostream> //debug output
#include <string>

using std::string;
using std::cout;
using std::endl;

//the string to convert
string examplestring = "this is the example string for spaces into %20";

int main()
{
    int countspaces = 0; //its faster to fill a known size
    for (auto &x : examplestring)if (x == ' ')countspaces++; //counts spaces

    string newstring; //declare new string
    newstring.resize(examplestring.size() + (countspaces*3)); //pre-set size to make it run faster

    int newstringiterator = 0; //keep track of new string location

    //if ' '(space), place %20 in newstring and add 3 to iteration
    //else just place the letter and iterate

    for (int i=0;i<examplestring.size();i++)
    {
        if (examplestring[i] == ' ') 
        { 
            newstring.insert(newstringiterator, "%20");
            newstringiterator += 3;
        }
        else newstring[newstringiterator++] = examplestring[i];
    }

  //final newstring is the original with %20 instead of spaces. 
  cout << newstring << endl;

  system("PAUSE"); //to read console output
  return 0; //return to zero
}

这将输出newstring,这是旧字符串&#39;%20&#39;而不是空格。