c - 字符串和无限循环中的堆栈粉碎

标签 c string loops segmentation-fault

stack smashing

陷入循环。 随机进入无限循环。 有时在第一次,有时在第二次。 然而代码很乱。逻辑是将一个字符串分成三个字符串,交替三次。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char    mstr[21];
void    split(char    str1[21]);
void    printx(char    strxyz[7]);
void    main()
{
    int    i,j,count=0;
    char    str[21];
    for(i=1;i<=21;i++)
    {
        str[i-1]=i;
        printf("%d\t",str[i-1]);
        if(i%7==0)
        {
            printf("\n");
        }
    }
    while(count<3)
    {
        split(str);
        count++;
    }
}
void    split(char    str1[21])
{   
    int    i,j=0,k,ans,n;
    char    strx[7],stry[7],strz[7];
    printf("\n\n*    *    *    *    *    split    *    *    *    *    *\n\n");
    for(i=0;i<21;)
    {
        for(n=0;j<7;n++)
        {
            strx[j]=str1[i];i=i+1;
            stry[j]=str1[i];i=i+1;
            strz[j]=str1[i];i=i+1;
            j=j+1;
        }
    }
    printf("enter    the    group\n");
    scanf("%d",&ans);
    switch(ans)
    {
        case    1:
            strcat(stry,strx);
            strcat(stry,strz);
            strcpy(mstr,stry);
            break;
        case    2:
            strcat(strx,stry);
            strcat(strx,strz);
            strcpy(mstr,strx);
            break;
        case    3:
            strcat(strx,strz);
            strcat(strx,stry);
            strcpy(mstr,strx);
            break;
        default:
            printf("invalid\n");
    }
printf("\n mstr values\n");
for(k=0;k<21;k++)
{
    printf("%d\t",mstr[k]);
}

}

void    printx(char    strxyz[7])
{
    int    i;
    printf("\n");
    for(i=0;i<7;i++)
    {
        printf("%d\t",strxyz[i]);
    }
}

第二个输出:

student@CSE-LAB3:~/Desktop/fdrive$ cc shuffle.c 学生@CSE-LAB3:~/Desktop/fdrive$ ./a.out

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21

          • 拆分 * * * * *

进入群组 2

mstr值 1 4 7 10 13 16 19 2 5 8 11 14 17 20 3 6 9 12 15 18 21

          • 拆分 * * * * *

进入群组 2

mstr值 1 4 7 10 13 16 19 2 5 8 11 14 17 20 3 6 2 5 8 11 14

          • 拆分 * * * * *

进入群组 1 段错误(核心转储)

edited:

the string 

str = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

now we have to split the string into three. 
so.
strx = 1 2 3 4 5 6 7 
stry = 8 9 10 11 12 13 14 
srtrz = 15 16 17 18 19 20 21

now based on the input (1 or 2 or 3 ) merge the string into a single string.
if the input is 1. place the string strx( first sub string ) in the middle. so it becomes 
like stry+strx+strz

> output
> 1 4 7 10 13 16 19
> 2 5 8 11 14 17 20
> 3 6 9 12 15 18 21

logic: Imagine a real life problem.You have 21 cards. You divide it into three stacks of 7 cards. You ask your friend to think of a card from the three stacks.You then ask which stack has the card. The stack that contains the card is placed in the middle of other two stacks and merged without changing the order. Now You have to split the stack of 21 cards into 7 cards stacks . The process is repeated 3 times i.e. he has to choose the stack 3 times.

最佳答案

您有几个基本问​​题。最糟糕的是你没有用 '\0' 终止你的字符串。人物。这会导致未定义的行为。此外,您还可以连接,例如 strxstry 。但是字符数组strx[]没有空间了保存附加字符。

您可以通过更改大小为 21 的数组的所有声明来解决这些问题。至22 ,例如 char mstr[22]; ,并更改大小为 7 的数组的所有声明至8 ,例如 char strx[8]; 。那么你需要确保添加NUL每个字符串末尾的终止符。实现此目的的一种方法是将每个数组进行零初始化。另一种方法是显式添加 NUL字符,这就是我在下面的代码中所做的。

然后,您需要更改组合字符串的代码。此代码应将第一个子字符串复制到 mstr[] 中,然后连接接下来的两个子字符串:

case    1:
        strcpy(mstr,stry);
        strcat(mstr,strx);
        strcat(mstr,strz);

分割字符串的代码中还存在一个严重的逻辑错误。您拥有的双循环超出了数组范围。考虑一下当 i达到20 ,您将拥有:strz[j]=str1[22];i=22+1; ,自 i已经增加了两次。这应该简化为:

for(i=0, j=0; j < 7; j++, i += 3)
{
    strx[j] = str1[i];
    stry[j] = str1[i + 1];
    strz[j] = str1[i + 2];
}
strx[j] = '\0';
stry[j] = '\0';
strz[j] = '\0';

听起来您想保留每次调用 split() 期间所做的更改,所以你应该删除 str[]来自main()而是使用全局 mstr[]在这里,因为这是您存储打乱结果的字符串。不过,最好完全删除全局变量,因为最好仅在必须时才使用全局变量。自 split()函数分配 str1 的内容每个字符串之间strx , stry ,和strz ,您可以将合并结果存储回 str1 。自从 str1是指向 mstr[] 第一个元素的指针,更改在调用函数中可见。为了实现这一点,需要声明 mstr[]需要移入main() ,组合字符串的代码应如下所示:

case    1:
    strcpy(str1,stry);
    strcat(str1,strx);
    strcat(str1,strz);

这是修改后的代码,或多或少符合我认为您的意图。我还添加了一些代码来在三次调用 split() 后打印结果数组。 :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void    split(char    str1[22]);
void    printx(char    strxyz[8]);

int main(void)
{
    int    i,count=0;
    char    mstr[22];

    for(i=0;i<21;i++)
    {
        mstr[i]=i+1;
        printf("%d\t",mstr[i]);
        if((i+1)%7==0)
        {
            printf("\n");
        }
    }
    mstr[i] = '\0';

    while(count<3)
    {
        split(mstr);
        count++;
    }

    printf("\nResults:\n");
    for(i=0;i<21;i++)
    {
        printf("%d\t",mstr[i]);
        if((i+1)%7==0)
        {
            printf("\n");
        }
    }
}

void    split(char    str1[22])
{   
    int    i,j,k,ans;
    char    strx[8],stry[8],strz[8];
    printf("\n\n*    *    *    *    *    split    *    *    *    *    *\n\n");

    for(i=0, j=0;j<7;j++, i+=3)
    {
        strx[j]=str1[i];
        stry[j]=str1[i+1];
        strz[j]=str1[i+2];
    }
    strx[j] = '\0';
    stry[j] = '\0';
    strz[j] = '\0';

    printf("enter    the    group\n");
    scanf("%d",&ans);
    switch(ans)
    {
    case    1:
        strcpy(str1,stry);
        strcat(str1,strx);
        strcat(str1,strz);

        break;
    case    2:
        strcpy(str1,strx);
        strcat(str1,stry);
        strcat(str1,strz);

        break;
    case    3:
        strcpy(str1,strx);
        strcat(str1,strz);
        strcat(str1,stry);

        break;
    default:
        printf("invalid\n");
    }
    printf("\n str1 values\n");
    for(k=0;k<21;k++)
    {
        printf("%d\t",str1[k]);
    }
}

void    printx(char    strxyz[8])
{
    int    i;
    printf("\n");
    for(i=0;i<7;i++)
    {
        printf("%d\t",strxyz[i]);
    }
}

关于c - 字符串和无限循环中的堆栈粉碎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41843382/

相关文章:

c - sizeof 与字符串的行为

c++ - do-while 循环问题 : Try to develop a simple game

javascript - 为什么复杂循环和许多循环之间存在如此巨大的性能差异

php - 试图找出为什么我的 foreach 导入不起作用

python - 字符串的基本递归?

java - 如何验证字符串数组是否按字母顺序排序或不使用 java?

c - 如何将 GNU readline 与 flex-lexer 一起使用?

c - 将一个进程的标准输出重定向到两个进程

ios - 如何从c方法iOS调用objective c方法

从 C 中的文件输入创建二维数组