c++ - 将旧 cstring 的标记连接到新的 c 字符串

标签 c++ runtime-error c-strings palindrome

我们的教授给了我们一个回文作业,在这个作业中我们需要编写一个函数来删除所有标点符号、空格,并将 c 字符串 中的大写字母转换为小写字母。 我遇到的问题是当我调试/运行它时,在我输入函数的 cstring 后,它给出了“调试断言失败”错误,并且只给出了 c 字符串输入的小写字母版本的输出。有没有人建议我如何修复或改进这段代码?

更新:我通过将字符串标记为 geeksforgeeks 来修复我的错误做过。但现在我遇到的问题是,当将 s cstring 的标记连接到 new_s c 字符串时,它只连接 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);
}

我的输出是:

输入一行:
汉娜看到蜜蜂了吗?汉娜做到了!
是回文

最佳答案

首先,正如@M.M 所说,当你想继续标记同一个字符串时,你应该调用 strk(NULL, "..") , 不适用于 '\0' .

其次,你的程序逻辑没有多大意义。您拆分字符串 s成子字符串,但实际上从未将它们连接到 new_s .当你到达第二个时,tokenptr肯定是NULL , 所以你永远不会进入循环。

为了修复您的代码,我将两个 while 合并为一个 while 并添加了一个 if 以不调用 strcat(new_s, tokenptr)如果tokenptr为空。

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);
}

P.S:我使用了非安全版本的 cstring 函数,因为出于某种原因,我的编译器不喜欢安全版本。

关于c++ - 将旧 cstring 的标记连接到新的 c 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58349727/

相关文章:

objective-c - 发送到释放实例的 CFDictionary objectForKey 消息

python - 迭代字典时出现奇怪的运行时错误

java - 我的代码没有错误,但也没有结果

syntax-error - .at(i)上的编译错误,但[i]上没有

c++ - 从 char 数组转换/提取整数

c++ 创建新对象时 : iterator not incrementable

c++ - VS 2012(视觉 C): error C2143: syntax error: miss ";" before "*"

c++ - 为什么我不能用类函数重载非类函数?

c++ - Cython 和类的构造函数

c++ - 使用strchr的作业问题给了我意外的输出