从字符串中删除元音,Stack smashing error

时间:2016-08-01 08:22:47

标签: c string

#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中。但每当我执行它时,堆栈粉碎错误就会出现。为什么呢?

7 个答案:

答案 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