所以,我想做的是放置一个' 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
答案 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的意图'在这个位置“。