#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "my name is khan. and i am not a terrorist\n";
char arr[80];
char wolf[] = { 'a', 'e', 'i', 'o', 'u', '\0' };
int i, j, k, len;
len = strlen(str);
for (i = 0, j = 0; i < len; i++) {
for (k = 0; k <= 4; k++) {
if (wolf[k] != str[i]) {
arr[j] = str[i];
j++;
}
}
}
return 0;
}
在这里,我必须从字符串str
中删除元音。我将结果字符串存储在arr
中。但每当我执行它时,堆栈粉碎错误就会出现。为什么呢?
答案 0 :(得分:2)
处理char时会发生什么?
你会写5次到arr。一般来说,所有字符都会写4到5次。
不要在内循环中写入arr。而是使用标记来记住您是否匹配。在循环之后测试标志以查看是否要写入char。
答案 1 :(得分:1)
你在检查中有错误,如果characheters不是元音,你是复制相同的characheter 5次。你应该以这种方式进行检查
for(i=0,j=0;i<len;i++)
{
unsigned char isvowel = 0;
for(k=0;k<=4;k++)
{
if(wolf[k]==str[i])
{
isvowel = 1;
break;
}
}
if (!isvowel) {
arr[j]=str[i];
j++;
}
}
或者你可以开发一个单独的函数来检查charachter是否是元音:
unsigned char isvowel(char c)
{
char wolf[]={'a','e','i','o','u','\0'};
int k;
for(k=0;k<=4;k++)
{
if(wolf[k]==c)
{
return 1;
}
}
return 0;
}
你可以用这种方式在你的for循环中使用它:
for(i=0,j=0;i<len;i++)
{
if (!isvowel(str[i]) {
arr[j]=str[i];
j++;
}
}
顺便说一句,您必须在arr
字符串的末尾添加null charachter。在for循环之后添加以下行:
arr[j] = '\0';
答案 2 :(得分:1)
由于进行了大量的比较,您可能会遇到缓冲区溢出(可能)。这部分代码:
if(wolf[k]!=str[i]){
arr[j]=str[i];
j++;
}
每次出现不匹配时,似乎都会改变j的值。例如,假设第一个字符'm',最终会在'arr'数组中被复制多次。
答案 3 :(得分:0)
Stack smashing
表示您正在非法使用堆栈(计算机内存的一部分)。非法使用堆栈内存可以通过多种方式完成。一种方法是向阵列添加比其容量更多的元素。例如,如果您尝试将15个元素添加到容量为10个元素的数组中,那么您将拥有stack smashing
。
在您的情况下,数组char arr[80];
具有80
个字符的容量,但您在此数组中添加了超过80个字符。这就是您收到stack smashing
错误的原因。
您的代码中存在两个问题。首先,您要将str[]
的元素多次添加到arr[]
。
/* Issue 1 */
for(k=0;k<=4;k++)
{
if(wolf[k]!=str[i])
{
/* You are adding str[i] to
arr[] multiple times
*/
arr[j]=str[i];
j++;
}
}
在这里,您要将str[i]
与每个元音字符进行比较,并且每次都将该字符添加到arr[]
。这样每个字符加5次(非元音字符),或4次(元音字符)。
要解决此问题,您需要将str[i]
与所有元音进行比较,并且只有在与任何元音不匹配时才将其添加到arr[]
。有很多方法可以做到这一点。例如,您可以使用其他变量作为标志。
其次,您没有检查arr[]
中是否还有空格来添加任何新字符。在这部分代码中:
/* Issue 2: You are not checking if space left in arr[] */
for(i=0,j=0;i<len;i++)
{
在你的for循环条件中,你需要确保arr []
中还剩下空格。因此,您需要在for循环中再添加一个条件。
这是(众多)解决方案中的一个:
/* Check if space left in arr, i.e. j < 80 */
for(i=0,j=0;i<len && j < 80;i++)
{
/* Add a flag:
1 means vowel
0 means not a vowel
*/
int v_flag = 0;
for(k=0;k<=4;k++)
{
if(wolf[k] == str[i])
{
v_flag = 1; /* Indicate that this is vowel */
break;
}
}
/* Add to arr[] only if not a vowel */
if (v_flag == 0)
{
arr[j] = str[i];
j++;
}
}
/* Null terminate the string */
arr[j] = '\0';
答案 4 :(得分:0)
我使用flag
修改了您的代码,最后您错过了arr[j]='\0';
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[]="my name is khan. and i am not a terrorist";
char arr[80]={0};
char wolf[]={'a','e','i','o','u','\0'};
int i,j,k,len,flag=0;
len=strlen(str);
for(i=0,j=0;i<len;i++)
{
for(k=0;k<=4;k++)
{
if(wolf[k]==str[i])
{
flag = 1;
break;
}
}
if(0==flag)
{
arr[j]=str[i];
j++;
}
flag=0;
}
arr[j]='\0';
printf("str:%s\n",str);
printf("arr:%s\n",arr);
return 0;
}
这可能与之前的答案相同。
答案 5 :(得分:0)
标准库中有一些字符串函数可以帮助你,strchr()就是其中之一(你可以摆脱内循环!):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[] = "my name is khan. and i am not a terrorist\n";
char arr[80];
char *wolf = "aeiouy";
int i,j;
for(i=j=0; arr[j] = str[i]; i++)
{
if ( !strchr (wolf, str[i]) ) j++;
}
printf("%s\n", arr);
return 0;
}
答案 6 :(得分:0)
对于每个失败的比较,您实际上是将arr
中的字符复制到元音。生成的字符串比原始字符串 4到5倍,比目标数组#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "my name is khan. and i am not a terrorist\n";
char arr[80];
char wolf[] = { 'a', 'e', 'i', 'o', 'u', '\0' };
int i, j, k, len;
len = strlen(str);
for (i = 0, j = 0; i < len; i++) {
for (k = 0; k < 5; k++) {
if (str[i] == wolf[k])
break;
}
if (k == 5) { // not a vowel
arr[j] = str[i];
j++;
}
}
arr[j] = '\0'; // remember to put the final null byte to close the C string
printf("result: %s\n", arr);
return 0;
}
长得多。超出数组末尾的写入会调用未定义的行为:在您的情况下提前终止程序。
以下是解决问题的方法:
setAdapter