在第二次调用 strtok() 期间,代码引发以下错误:大小 1 的读取无效

问题描述 投票:0回答:1

我是 C++ 新手,我不明白为什么代码不继续标记文本数组,而是引发错误。

我怀疑问题可能是由于在标记化过程中传递了标记 ptr,导致代码放弃,或者其他原因。

任务如下:

编写一个函数,删除给定文本中出现多次的所有单词。
另请注意,WORD 是由空格分隔的字母序列。
笔记。程序必须使用指针。

输入:
第一行包含不超过 1000 个带有空格的符号的行。
每个单词不超过 30 个符号。

输出:
格式化文本。

#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;

bool compareThem(char* lhs, char* rhs) {
    if (strcmp(lhs, rhs) != 0) {
        return false;
    }
    int len = strlen(lhs);

    for (int i = 0; i < len; i++) {
        if (!(lhs[i] == rhs[i])) {
            return false;
        }
    }
    return true;
}

bool isDuplicate(char* possibleDuplicate, char* result) {
    char* soFar = new char[strlen(result) + 1]; 
    strcpy(soFar, result); 

    char* word = strtok(soFar, " ");
    while (word != NULL) {
        if (compareThem(possibleDuplicate, word)) {
            delete[] soFar; 
            return true;
        }
        word = strtok(NULL, " ");
    }

    delete[] soFar; 
    return false;
}

void removeDuplicates(char* text) {
    char* result = new char[1000];
    result[0] = '\0';

    char* word = strtok(text, " ");
    while (word != NULL) {
        if (!isDuplicate(word, result)) {
            strcat(result, word);
            strcat(result, " ");
        }
        word = strtok(NULL, " ");
    }

    cout << result;

    delete[] result;
}

int main() {
    char* str = new char[1000];
    cin.getline(str, 1000);

    removeDuplicates(str);

    delete[] str;
    return 0;
}
c++ pointers c-strings dynamic-arrays strtok
1个回答
0
投票

strtok()
不可重入。您一次只能使用它标记 1 个字符串。由于您尝试一次标记 2 个字符串,因此需要使用
strtok_r()
来代替。

话虽如此,您的代码是 C 和 C++ 逻辑的混合。更好的解决方案是完全接受

std::string
等 C++ 习惯用法和标准算法,并且根本不使用任何 C 函数。

© www.soinside.com 2019 - 2024. All rights reserved.