我对c中的strcpy()感到困惑

时间:2014-06-03 13:41:33

标签: c structure strcpy

我正在为堆栈编写push()操作,其中堆栈中的每个项目都是一个字符串,同时这样做我写了推送操作

void push(char *str)
{
  stack.top++;
  strcpy(stack.arr[stack.top],"");
  strcpy(stack.arr[stack.top],str);
}

其中stack是struct type的全局变量

struct s
{
   char arr[30][40];;
   int top;
};

struct s stack;

令我惊讶的是,即使在推送操作后,我发现堆栈元素的值总是“”, 然后我注释掉了

strcpy(stack.arr[stack.top],"");

现在堆栈中的项目包含正确的str值。

我的问题是为什么第一种方法涉及首先通过strcpy(item,“”)将项初始化为null,然后strcpy(item,str)不能成功地使用str中包含的值分配堆栈项?

对于那些想要在这里看到整个代码的人来说...... 如果你请问我的问题,请让我知道为什么,我最初没有提到代码,以使问题尽可能简洁,我不认为我应该得到downvote

/*postfix to infix.working*/

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

struct s
{
    char arr[40][50];
    int top;
};

void post_to_in(char input[50]);
void push(char *str);
char* pop();
void init();

struct s stack;

int main(void)
{
    char input[50];

    printf("enter the input string\n");
    scanf("%s",input);

    init();

    post_to_in(input);

   /* printf("the infix expression is \n");
    printf("%s",output);*/
    return 0;
}

void post_to_in(char input[50])
{
    int len=0;
    int i;
    char buf[2];
    char *item1,*item2;

    for(i=0;input[i]!='\0';i++)
    {
        ;
    }
    len = i;
    /*abc, len =3 */

    for(i=0;i<len;i++)
    {
        if(isalnum(input[i]))
        {
            sprintf(buf,"%c",input[i]);
            push(buf);
            continue;
        }

        /*if control here, implies input[i] is an operator*/
        item1 = pop();
        item2 = pop();

        sprintf(buf,"%c",input[i]);
        strcat(item2,buf);
        strcat(item2,item1);
        push(item2);
    }

    item1 = pop();

    printf("the infix expression is \n");
    printf("%s",item1);
}


void push(char *str)
{
    stack.top++;
    strcpy(stack.arr[stack.top],str);
}

char* pop()
{
    if(stack.top==-1)
    {
        printf("this shouldnt be happening\n");
        return "";
    }
    return stack.arr[stack.top--];
}

void init()
{
    stack.top =-1;
}

1 个答案:

答案 0 :(得分:1)

问题是当你pop时,你会将指针返回到堆栈结构中。

item1将指向stack.arr[stack.top],因此当您按下时,您将覆盖输入。

即使您没有额外的pushstrcpy也会调用未定义的行为,因为strcpy的源和目标字符串重叠(事实上,它们是相同!)。

解决方法是在编写中缀表达式时使用单独的缓冲区:

    /*if control here, implies input[i] is an operator*/
    char buffer[50];   // Added this line
    item1 = pop();
    item2 = pop();

    /* Replaced code: 
    sprintf(buf,"%c",input[i]);
    strcat(item2,buf);
    strcat(item2,item1);
    push(item2);
    */
    // New code
    sprintf(buffer, "%s%c%s", item2, input[i], item1);
    push(buffer);

修改

演示问题的示例。输入字符串= 34+

获取+时的堆栈结构:

top = 1
"3"   // stack.buf[0]
"4"   // stack.buf[1]

之后,您pop进入item1item2

item1 = pop();
item2 = pop();

Item1和item2现在指向堆栈结构:

top = -1
"3"   // stack.buf[0]  item2 points to this location
"4"   // stack.buf[1]  item1 points to this location

然后修改项目2.在调用push之前,堆栈结构将如下所示:

top = -1
"3+4" // stack.buf[0]  item2 points to this location
"4"   // stack.buf[1]  item1 points to this location

然后你打电话给推。 top已更改为0。 然后调用strcpy,如果你第一次写'&#34}&#34;然后输入被覆盖,堆栈结构将如下所示:

top = 0
"" // stack.buf[0]  item2 points to this location - You push to this location, but the source string is at the same location!!!
"4"   // stack.buf[1]  item1 points to this location