【问题标题】:Inserting string into stack returns random character将字符串插入堆栈返回随机字符
【发布时间】:2021-06-08 08:02:29
【问题描述】:

正在将一个字符串推送到我的堆栈上,目前我正在获取随机字符(字符没有被推送到堆栈上,因为当我事后检查时我的堆栈是空的)

这里是相关的功能和结构

typedef char stackitem;

struct stack {
stackitem  d;
struct stack *next;
};

typedef  struct stack ELEMENT;
typedef  ELEMENT   *POINTER;

void push(POINTER *Top, stackitem a)
/* Put item a into the top of the stack */
     {
        POINTER temp;
        temp = malloc(sizeof(ELEMENT));
        temp->d = a;
        temp->next = *Top;
        *Top = temp;
        printf("Insert element %c\n", temp->d);
     }
void push_string(POINTER *Top,char *string)
/* Push a string of characters into a stack. */
    {
        char *tmp = malloc(strlen(string) + 1);
        if (tmp)
        strcpy(tmp, string);
    push(&Top,tmp);

我在另一个 SO 线程上找到的第二个函数的一部分。 这就是我使用它的方式:

main()
    {
    POINTER top;
        top= (POINTER) NULL;
        stackitem A='A';
        stackitem B='B';
        char *C="12345";
        push_string(&top,C);
        print_stack(top);

        return 0;
   }
      

如何将字符串添加到堆栈中? push 函数用于将字符推送到堆栈上,但我无法让它推送整个字符串。

【问题讨论】:

  • 显然,您的堆栈(您未显示其定义)可以保存字符,但不能保存字符串。将整个字符串压入堆栈的一种方法是压入所有字符,因此不要尝试压入"ABC",而是遍历字符串并压入'A''B''C'
  • ive 更新了我的帖子的定义...不会循环遍历字符串将每个字符作为单独的元素推送到堆栈上吗?这是针对一些 uni 任务的,我相信其目的是将字符串推入堆栈
  • typedef ELEMENT *POINTER; 被认为是一种不好的做法。使用ELEMENT* 以便读者可以看到它是一个指针。
  • 这段代码没有警告吗?在我看来,编译器会立即发现问题!确保启用编译器的警告(例如 -Wall -Wextra -pedantic 与 gcc/clang)
  • @william_ 函数 push_string 没有意义。

标签: c struct stack c-strings function-definition


【解决方案1】:

函数push_string的代码sn-p原样没有意义。

例如,不需要创建传递字符串的副本。

    char *tmp = malloc(strlen(string) + 1);
    if (tmp)
    strcpy(tmp, string);

其次是这个电话

push(&Top,tmp);

有无效的参数类型。

函数push_string可以如下所示

void push_string( POINTER *Top, const char *string )
{
    for ( ; *string; ++string ) push( Top, *string );
}

这是一个演示程序。

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

typedef char stackitem;

struct stack {
stackitem  d;
struct stack *next;
};

typedef  struct stack ELEMENT;
typedef  ELEMENT   *POINTER;

int push( POINTER *Top, stackitem c )
{
    POINTER temp = malloc( sizeof( ELEMENT ) );
    int success = temp != NULL;
    
    if ( success )
    {
        temp->d = c;
        temp->next = *Top;
        *Top = temp;
    }
    
    return success;
}

void push_string( POINTER *Top, const char *string )
{
    for ( ; *string; ++string ) push( Top, *string );
}

int pop( POINTER *Top, stackitem *c )
{
    int success = *Top != NULL;
    
    if ( success )
    {
        *c = ( *Top )->d;
        POINTER temp = *Top;
        *Top = ( *Top )->next;
        free( temp );
    }
    
    return success;
}

int main(void) 
{
    POINTER top = NULL;
    
    push_string( &top, "12345" );
    
    for ( char c; pop( &top, &c ); )
    {
        putchar( c );
    }
    putchar( '\n' );
    
    return 0;
}

程序输出是

54321

请注意,您应该检查堆栈新节点的内存分配是否成功。

在演示程序中,函数push 报告推送元素是否成功。

函数push_string 也应该报告一个字符串是否被成功推送。在这种情况下,它可以通过以下方式定义

int push_string( POINTER *Top, const char *string )
{
    while ( *string && push( Top, *string ) ) ++string;
  
    return *string == '\0';
}

只需将上面演示程序中的函数push_string 替换为这个函数,程序就会按预期运行。

【讨论】:

    【解决方案2】:

    首先,打开所有警告(选项-Wall -pedantic)。 编译器可能会抱怨不兼容类型之间的转换。

    函数push()专用于将单个char放入堆栈,而push_string()专用于将string的所有字符一个一个地放入。

    因此,要放置一个字符串,您应该单独放置字符串的每个字符。

    void push_string(POINTER *Top,char *string) {
      for (char *s = string; *s; ++s)
        push(Top, *s);
    }
    

    【讨论】:

    • 关于循环的快速问题,条件 *s; 是什么?代表?
    • @william_, *s 正在检查 s 指向的字符。循环继续,直到遇到 0 值(字符串终止符)。值 0 是 C 中的 false
    猜你喜欢
    • 2016-02-07
    • 2011-04-22
    • 2021-12-01
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 2018-12-30
    相关资源
    最近更新 更多