объединение токенов старого cstring в новую c-строку - PullRequest
0 голосов
/ 12 октября 2019

Наш профессор дал нам палиндромное задание, и в этом задании нам нужно написать функцию, которая удаляет все знаки препинания, пробелы и преобразует прописные буквы в строчные буквы в c-string . Проблема, которую я получаю, состоит в том, что, когда я отлаживаю / запускаю ее, после того, как я ввожу cstring для функции, она выдает ошибку «Ошибка отладки» и выводит только строчную букву версии ввода c-строки. У кого-нибудь есть предложения, как я могу исправить или улучшить этот кусок кода?

Обновление: я исправил свою ошибку, пометив строку как geeksforgeeks . Но теперь проблема, с которой я сталкиваюсь, заключается в том, что при объединении токенов s cstring в new_s c-string он объединяет только первый токен с s на new_s . Это мой код:

#define _CRT_SECURE_NO_WARNINGS //I added this because my IDE kept giving me error saying strtok is unsafe and I should use strtok_s. 
#include <iostream>
#include <iomanip>
#include <cstring>
using namespace  std;

/*This method removes all spaces and punctuation marks from its c-string as well as change any uppercase letters to lowercase. **/
void removePuncNspace(char s[])
{
    char new_s[50], *tokenptr;

    //convert from uppercase to lowercase
    for (int i = 0; i < strlen(s); i++) (char)tolower(s[i]);

    //use a cstring function and tokenize s into token pointer and eliminate spaces and punctuation marks
    tokenptr = strtok(s, " ,.?!:;");

    //concatenate the first token into a c-string.
    strcpy_s(new_s,tokenptr);

    while (tokenptr != NULL)
    {
        tokenptr = strtok('\0', " ,.?!:;"); //tokenize rest of the string
    }

    while (tokenptr != NULL)
    {
        // concat rest of the tokens to a new cstring. include the \0 NULL as you use a cstrig function to concatenate the tokens into a c-string.
        strcat_s(new_s, tokenptr);
    }

    //copy back into the original c - string for the pass by reference.
    strcpy(s, new_s);
}

Мой вывод:

Введите строку:
Видела ли Ханна пчел? Ханна сделала!
Сделала это палиндром

1 Ответ

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

Во-первых, как сказал @MM, когда вы хотите продолжить токенизацию той же строки, вы должны вызвать strk(NULL, ".."), а не с '\0'.

Во-вторых, логика вашей программы не имеет большого смысла,Вы разбиваете строку s на подстроки, но никогда не объединяете их в new_s. К тому времени, когда вы перейдете ко второму времени, tokenptr, несомненно, будет NULL, поэтому вы никогда не войдете в цикл.

Чтобы исправить ваш код, я объединил два while в один и добавил оператор if кне вызывайте strcat(new_s, tokenptr), если tokenptr равен NULL.

void removePuncNspace(char s[])
{
    char new_s[50], *tokenptr;

    //convert from uppercase to lowercase
    for (int i = 0; i < strlen(s); i++) (char)tolower(s[i]);

    //use a cstring function and tokenize s into token pointer and eliminate spaces and punctuation marks
    tokenptr = strtok(s, " ,.?!:;");

    //concatenate the first token into a c-string.
    strcpy(new_s,tokenptr);

    while (tokenptr != NULL)
    {
        tokenptr = strtok(nullptr, " ,.?!:;"); //tokenize rest of the string
        if (tokenptr != NULL)
            strcat(new_s, tokenptr);
    }

    //copy back into the original c - string for the pass by reference.
    strcpy(s, new_s);
}

PS: я использовал небезопасные версии функций cstring, потому что по какой-то причине мой компилятор не любит безопасные.

...