Невозможно перевернуть простую строку, используя функцию Pop () стека - PullRequest
0 голосов
/ 31 октября 2019

У меня есть простая программа стека, которая пытается перевернуть строку. Я могу «отобразить» перевернутую строку, но когда дело доходит до сохранения символа, возвращаемого функцией Pop (), я не могу это сделать. Что я делаю ниже, так это то, что в main() после того, как я поместил строку в стек, я пытаюсь использовать повторное использование str[] для хранения перевернутой строки. Поскольку это массив, я должен быть в состоянии изменить его. Однако, когда я делаю это, по какой-то странной причине цикл for выполняется только ОДИН раз. Я предполагаю, что это происходит потому, что во pop() *head = NULL во второй итерации и, следовательно, он не работает.

Я не могу запустить цикл for более одного раза. У меня вопрос: что мешает мне сохранить обратную строку?

1) Почему цикл for работает только один раз, когда я использую str [i]?

2) Использую ли яstr [i] каким-то странным образом, который вызывает это?

char ret = '\0';
void Push(Node **head, char data)
{
    Node *temp = (Node*)malloc(sizeof(Node));
    temp->data = data;
    temp->next = NULL;
    if (*head == NULL)
    {
        *head = temp;
        return;
    }

    temp->next = *head;
    *head = temp;
    return;
}

void PrintAll(Node *temp)
{
    if(temp == NULL) return;
    printf("%c, ", temp->data);
    PrintAll(temp->next);
}
char Pop(Node **head)
{
    if(*head == NULL)  
    {
        return '\0';
    }
    Node *temp = *head;
    ret = temp->data;
    *head = (*head)->next;
    free (temp);
    return ret;
}

int main()
{
    Node *head = NULL;

    char str[] = "helloworld";
    printf("Original String is:%s\n", str);
    printf("Length is:%lu\n", strlen(str));

    for (int i = 0; i <=strlen(str); i++)
    {
        Push(&head, str[i]);
    }

    printf ("String has been pushed to the stack.\n");
    PrintAll(head);
    printf("\nString has been printed. Now popping:%ld.\n", strlen(str));


    //Problem starts here in this for-loop
    for (int i = 0; i <=strlen(str); i++)
    {
        str[i] = Pop(&head); //When these next lines are enabled, the for-loop runs only once!
        printf("%c, ", str[i]); //Pop() is returning the value from a global variable 'ret'
        //printf("%c ", Pop(&head)); //if two previous lines are disabled, string is displayed in reverse

    }
    printf("\n");
    printf ("String has been popped from the stack.\n");
    return 0;
}

1 Ответ

1 голос
/ 31 октября 2019

Последнее, что вы поместили в стек, был нулевой терминатор строки. Итак, первое, что вы выбрали, был этот нулевой терминатор. Когда вы присвоили str[i] = Pop(&head);, вы сделали первый символ нулевым терминатором. В результате strlen(str) теперь равно 0, и цикл останавливается на следующей итерации, поскольку 1 <= 0 не соответствует действительности.

Не следует помещать нулевой терминатор в стек. В первом цикле следует использовать i < strlen(str), а не i <= strlen(str) (более эффективный способ будет str[i] != 0).

И при выводе сообщения вы не должны использовать strlen() полученной строки, так как выпока не знаю, как долго это будет. Вы должны вызывать Pop(&head) до тех пор, пока он не вернет '\0', что означает, что вы очистили стек.

int main()
{
    Node *head = NULL;

    char str[] = "helloworld";
    printf("Original String is:%s\n", str);
    printf("Length is:%lu\n", strlen(str));

    for (int i = 0; str[i] != 0; i++)
    {
        Push(&head, str[i]);
    }

    printf ("String has been pushed to the stack.\n");
    PrintAll(head);
    printf("\nString has been printed. Now popping:%ld.\n", strlen(str));

    for (int i = 0; str[i] = Pop(&head); i++)
    {
        printf("%c, ", str[i]); //Pop() is returning the value from a global variable 'ret'
    }
    printf("\n");
    printf ("String has been popped from the stack.\n");
    return 0;
}
...