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



堆栈粉碎

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

#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("%dt",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("nn*    *    *    *    *    split    *    *    *    *    *nn");
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    groupn");
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("invalidn");
}
printf("n mstr valuesn");
for(k=0;k<21;k++)
{
printf("%dt",mstr[k]);
}
}
void    printx(char    strxyz[7])
{
int    i;
printf("n");
for(i=0;i<7;i++)
{
printf("%dt",strxyz[i]);
}
}

第二次输出:

student@CSE-LAB3:~/桌面/fdrive$cc shuffle.cstudent@CSE-LAB3:~/桌面/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 8 11 14

          • 拆分****

进入组1.分段故障(堆芯转储)

编辑:

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

逻辑:想象一下现实生活中的问题。你有21张牌。你把它分成三堆7张牌。你让你的朋友从三叠卡片中想出一张。然后你问哪一张牌有。包含卡片的堆叠被放置在其他两个堆叠的中间,并在不改变顺序的情况下合并。现在你必须把21张牌分成7张牌。该过程重复3次,即他必须选择堆栈3次。

您有几个基本问题。最糟糕的是,您没有使用''字符终止字符串。这会导致未定义的行为。此外,您正在连接,例如,strxstry。但是在字符阵列strx[]中没有容纳附加字符的空间。

您可以通过将大小为2122(例如char mstr[22];)的数组的所有声明更改为78(例如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] = '';
stry[j] = '';
strz[j] = '';

听起来你想保留每次调用split()时所做的更改,所以你应该从main()中删除str[],而在这里使用全局mstr[],因为这是你存储混洗结果的字符串。不过,完全删除全局要好得多,因为最好只在时使用全局。由于split()函数将str1的内容分布在每个字符串strxstrystrz中,因此可以将组合结果存储回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("%dt",mstr[i]);
if((i+1)%7==0)
{
printf("n");
}
}
mstr[i] = '';
while(count<3)
{
split(mstr);
count++;
}
printf("nResults:n");
for(i=0;i<21;i++)
{
printf("%dt",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("nn*    *    *    *    *    split    *    *    *    *    *nn");
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] = '';
stry[j] = '';
strz[j] = '';
printf("enter    the    groupn");
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("invalidn");
}
printf("n str1 valuesn");
for(k=0;k<21;k++)
{
printf("%dt",str1[k]);
}
}
void    printx(char    strxyz[8])
{
int    i;
printf("n");
for(i=0;i<7;i++)
{
printf("%dt",strxyz[i]);
}
}

在过程拆分中,您有j<=7,但它应该是j<7j<=6,以防止越界问题。

在我看来,可能存在未初始化的值或终止循环的错误条件。

我发现了一个问题,例如在函数中

void    split(char str1[21])
{   
//i, k and n are later initialized but j is not.
int i,j,k,ans,n;
char strx[7],stry[7],strz[7];
printf("nn*    *    *    *    *    split    *    *    *    *    *nn");
for(i=0;i<21;)
{
//j is not initialized, how do you know compiler will initialize it to 0 for sure?
//j <= 7 should be j < 7
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 groupn");
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("invalidn");
}
printf("n mstr valuesn");
for(k=0;k<21;k++)
{
printf("%dt",mstr[k]);
}
}

在没有初始化的情况下声明j,然后在for循环中将其与7进行比较,其中n递增。每次程序启动时,它们都可能被初始化为一个随机值。这就是为什么你可能会收到未定义的行为。此外,j <= 7应为j < 7

相关内容

  • 没有找到相关文章

最新更新