C-wcstok()错误的结果

时间:2018-12-15 13:07:44

标签: c wchar-t

我的程序中有一个功能出现问题。我有一个包含句子的文本。在每个句子中,我需要找到符号'@','#','%',并将其更改为“(at)”,“ <решетка>”,“”。我正在使用wcstok进行此操作,因为我正在使用俄语。而且我有以下问题。

  

输入:

     
    

他是一个老人,独自一人在墨西哥湾流中的一条小艇上钓鱼,如今他已经走了八十四天而没有钓到一条鱼。在头四十天内,有一个男孩和他在一起。但是在四十天没吃鱼之后,男孩的父母告诉他,现在肯定是老人了,最后是sa @ lao,这是最不幸的一种形式,男孩顺着他们的命令去了另一条船上,抓住了三个好鱼。 #h第一周。

  
     

输出:

     
    

他是一个老人,独自一人在墨西哥湾流中的一条小艇上钓鱼,如今已经走了八十四天而没有钓到一条鱼。在头四十天内,有一个男孩和他在一起。 B(at)(at)f(at)er for(at)yd(at)ys wi(at)ho(at)(at)鱼(at)男孩的p(at)ren(at)sh(at) d(at)old his(at)h(at)(at)he老m(at)nw(at)s defini(at)ely(at)nd fin(at)lly s(at)l(at) o,这是(at)nl(at)cky的(at)形式,(at)nd男孩在(at)的命令中消失了(at)没有(至少)每周有三小时的好时光。

  

如您所见,它将所有字母“ a”和“ t”更改为“(at)”。而且我不明白为什么会这样。俄语字母也是如此。这是负责这项工作的两个功能。

void changeSomeSymbols(Text *text) {
wchar_t atSymbol = L'@';
wchar_t atString[5] = L"(at)";
wchar_t percentSymbol = L'%';
wchar_t percentString[10] = L"<percent>";
wchar_t barsSymbol = L'#';
wchar_t barsString[10] = L"<решетка>";
for (int i = 0; i < text->textSize; i++) {
    for (int j = 0; j < text->sentences[i].sentenceSize; j++) {
        switch (text->sentences[i].symbols[j])
        {
        case L'@':
            changeSentence(&(text->sentences[i]), &atSymbol, atString);
            break;
        case L'#':
            changeSentence(&(text->sentences[i]), &barsSymbol, barsString);
            break;
        case L'%':
            changeSentence(&(text->sentences[i]), &percentSymbol, percentString);
            break;
        default:
            break;
        }
    }
}

}

void changeSentence(Sentence *sentence, wchar_t *flagSymbol, wchar_t *insertWstr) {
wchar_t *pwc;
wchar_t *newWcsentence;
wchar_t *buffer;
int insertionSize;
int tokenSize;
int newSentenceSize = 0;
insertionSize = wcslen(insertWstr);
newWcsentence = (wchar_t*)malloc(1 * sizeof(wchar_t));
newWcsentence[0] = L'\0';
pwc = wcstok(sentence->symbols, flagSymbol, &buffer);
do {
    tokenSize = wcslen(pwc);
    newWcsentence = (wchar_t*)realloc(newWcsentence, (newSentenceSize + tokenSize + 1) * sizeof(wchar_t));
    newSentenceSize += tokenSize;
    wcscat(newWcsentence, pwc);
    newWcsentence = (wchar_t*)realloc(newWcsentence, (newSentenceSize + insertionSize + 1) * sizeof(wchar_t));
    newSentenceSize += insertionSize;
    wcscat(newWcsentence, insertWstr);
    pwc = wcstok(NULL, flagSymbol, &buffer);
} while (pwc != NULL);
newSentenceSize -= insertionSize;
newWcsentence = (wchar_t*)realloc(newWcsentence, (newSentenceSize) * sizeof(wchar_t));
newWcsentence[newSentenceSize] = '\0';
free(sentence->symbols);
sentence->symbols = (wchar_t*)malloc((newSentenceSize + 1) * sizeof(wchar_t));
wcscpy(sentence->symbols, newWcsentence);
sentence->sentenceSize = newSentenceSize;
free(pwc);
free(newWcsentence);

}

1 个答案:

答案 0 :(得分:1)

TextSentence未定义,尚不清楚它们应该是什么。只需执行一个功能即可。

void realloc_and_copy(wchar_t** dst, int *dstlen, const wchar_t *src)
{
    if(!src)
        return;
    int srclen = wcslen(src);
    *dst = realloc(*dst, (*dstlen + srclen + 1) * sizeof(wchar_t));
    if (*dstlen)
        wcscat(*dst, src);
    else
        wcscpy(*dst, src);
    *dstlen += srclen;
}

int main()
{
    const wchar_t* src = L"He was an old man who fished alone in a skiff \
in the Gulf Stream and he had gone eighty - four days now without tak%ing a fish.\
In the first forty days a boy had been with him.But after forty days without a fish \
the boy’s parents had told him that the old man was now definitely and finally sa@lao, \
which is the worst form of unlucky, and the boy had gone at their orders in another \
boat which caught three good fis#h the first week.";

    wchar_t *buf = wcsdup(src);
    wchar_t *dst = NULL;
    int dstlen = 0;

    wchar_t *context = NULL;
    const wchar_t* delimiter = L"@#%";
    wchar_t *token = wcstok(buf, delimiter, &context);
    while(token)
    {
        const wchar_t* modify = NULL;
        int cursor = token - buf - 1;
        if (cursor >= 0)
            switch(src[cursor])
            {
            case L'@': modify = L"(at)"; break;
            case L'%': modify = L"<percent>"; break;
            case L'#': modify = L"<решетка>"; break;
            }

        //append modified text
        realloc_and_copy(&dst, &dstlen, modify);

        //append token
        realloc_and_copy(&dst, &dstlen, token);

        token = wcstok(NULL, delimiter, &context);
    }

    wprintf(L"%s\n", dst);

    free(buf);
    free(dst);

    return 0;
}