c ++数组MEMMOVE错误

时间:2015-04-04 17:24:44

标签: c++ arrays string

所以,我想做的是放置一个' p'在所有元音之前,我都是这样做的,但由于memmove,char数组中充满了奇怪的符号。

#include<conio.h>
#include <cstring>

#include <iostream>
using namespace std;

int main()
{
    char s1[256];
    cin.get(s1,255);
    cin.get();
    for(int i=0;i<strlen(s1);i++)
    {
        if(strchr("aeiou",s1[i])){
            memmove(s1+i+1,s1+i,strlen(s1));
            // duplicating the vowel so i can replace it
            s1[i]='p';
            i++;            
        }
    }
    cout<<s1;
    getch();
return 0;
}

输入:oaie

1 个答案:

答案 0 :(得分:0)

在你的memmove通话中,你使用的是不正确的长度:

memmove(s1+i+1,s1+i,strlen(s1));

strlen(s1)是从头开始的字符串长度,不包括空终止符。所以有两个问题。首先,您需要从当前位置开始的字符串长度。其次,您希望长度包括空终止符,以便复制空终止符。

这些错误的结果是,如果第一个字符是元音,那么memove将覆盖空终止符,并且缓冲区中的额外垃圾将开始被处理,就好像它是字符串的一部分一样。

此外,memove将在缓冲区内的某些输入和垃圾中访问缓冲区外。

解决方案是使用正确的长度strlen(s1+i),并包含空终止符:

memmove(s1+i+1,s1+i,strlen(s1+i)+1);

cin.get(s1, 255)确实存储了一个空终止符,实际上你可以安全地给它正确的缓冲区大小:cin.get(s1, 256)


使用std::string可以避免这些错误:

#include <cstring>
#include <string>
#include <iostream>

int main() {
    std::string s1;
    std::getline(std::cin, s1);

    for (int i = 0; i < s1.size(); ++i) {
        if (std::strchr("aeiou", s1[i])) {
            s1.insert(i, "p");
            ++i;
        }
    }
    std::cout << s1 << '\n';
}

注意,这没有任何固定的缓冲区大小,不必特别考虑null终止符,不必弄清楚需要移动多少字节,并直接表达“插入”p的意图'在这个位置“。