错误指针:解析标记时无法评估表达式

Posted

技术标签:

【中文标题】错误指针:解析标记时无法评估表达式【英文标题】:bad pointer: expression can not be evaluated while parsing tokens 【发布时间】:2013-12-05 09:43:21 【问题描述】:

在解析令牌时,我的所有令牌指针都变坏了,当我签入调试器时,它说无法评估表达式。 错误:CX0030:错误:无法评估表达式 并且令牌的值是 0x00000000

我在这里遗漏了一些东西,我尝试了很多但无法纠正它。我知道它与 const 等指针声明有关,但进行更改无济于事。

Windows + Visual Studio 2010 和正在解析的文件是 unicode UTF16

code sn-p ------

    const wchar_t* const DELIMITER = L"\"";
wchar_t buf[MAX_CHARS_PER_LINE];
fin.getline(buf, MAX_CHARS_PER_LINE);
wchar_t* token[MAX_TOKENS_PER_LINE] = ;
token[0] = wcstok(buf, DELIMITER);
if (token[0]) // zero if line is blank
    
    int n = 0; 
         for (n = 0; n < MAX_TOKENS_PER_LINE; n++)   
        
            token[n] = wcstok(0, DELIMITER); // subsequent tokens   --> error ,pointer becomes bad

            if (!token[n]) break; // no more tokens  -------------> code does not go beyond this

buf 有整个文件(这是另一个问题,当我尝试读取行时它会在其中获取整个文件),有人可以帮我指出我在这里犯了什么错误吗?

【问题讨论】:

wchar_t* token = wcstok(buf, DELIMITER); 如果是C++,不推荐使用这个分词功能。 @Exceptyon ,我不明白你的意思,你的意思是我缺少声明吗?或者你的意思是我不应该将令牌用作数组? @chris ,它的 C++ ,我有我的其余代码(C++ 中几乎 2k 行,所以现在不能更改它),你有任何我可以解决的替代函数吗? @NeileshC, ***.com/questions/236129/how-to-split-a-string-in-c 【参考方案1】:

如果没有发现分隔符,您认为token[0] = wcstok(buf, DELIMITER); 将为 NULL 的假设是不正确的。会有代币;字符串的内容,很容易证明如下:

#include <iostream>
#include <cwchar>

int main()

    wchar_t data[] = L"NoDelimiter";
    wchar_t *ctx = nullptr, *token = wcstok(data, L"\"", &ctx);

    if (token != nullptr)
        std::wcout << token << std::endl;

    return 0;

输出

NoDelimiter

因此,这段代码:

token[0] = wcstok(buf, DELIMITER);
if (token[0]) // zero if line is blank

... 只有当它确实是一个真正的空白输入(即没有字符的空)时才是正确的。如果甚至有 一个 字符(例如讨厌的换行符),则该 eval 将为真,您将陷入 for 循环。但是你可以很容易地测试它是否是一个真正的空行,只需这样做:

if (buff[0]) // true if line is not blank

继续,因为您故意跳过第一个将我们带到的标记:

for (n = 0; n < MAX_TOKENS_PER_LINE; n++)   

    token[n] = wcstok(0, DELIMITER); // will save NULL if original line had no delimiters
    if (!token[n]) 
        break;  // will break here since token[n] is NULL

总之,你的逻辑循环是有缺陷的。在您跳过一个标记之前,您最好确保您确实阅读一个标记,该标记由您认为存在的内容分隔。如果没有别的,我建议您测试以确保字符串具有'"',然后再假设返回的数据为非空的原因是因为存在一个。正如我在上面所展示的,这不是wcstok() 返回令牌的唯一方式。


替代方法

有很多选项可以做我认为你正在尝试做的事情。这只是其中之一,您可以根据需要对其进行调整。

#include <iostream>
#include <sstream>
#include <algorithm>
#include <vector>

int main()

    wchar_t data[] = L"\"Test1\", \"Test2\", \"Test3\"";
    std::wistringstream iss(data);

    std::vector<std::wstring> tokens;
    std::wstring token;
    if (std::getline(iss, token, L'"') && std::getline(iss, token, L'"'))
    
        while (iss)
        
            // output the real token
            tokens.push_back(token);
            std::wcout << token << std::endl;
            std::getline(iss, token, L'"'); // skip separator to next "
            std::getline(iss, token, L'"'); // read through next "
        
    

    // tokens now has your "data" delimited tokens

    return 0;

【讨论】:

谢谢@whozcraig,我会在我的代码中检查这个实现【参考方案2】:

您丢失了第一个令牌,因为 n 从 0 开始。对于其余部分,我唯一能想到的就是这段代码可以从多个线程运行,因此 wcstok 中的静态缓冲区会被后续调用 wcstok(buf,分隔符)。这工作正常(来自单线程应用程序):

char buf[] = "1;2;3;4";

char *tok[10] =;

tok[0] = strtok(buf, ";");

if (tok[0])

    int n = 1;

    while ((tok[n] = strtok(0, ";")) != 0)
    
        n++;
    

【讨论】:

我故意跳过第一个标记(忘记在代码中注释),因为我不想要它(我将使用 " 作为分隔符,它总是在分隔符之前解析第一个标记),我不知道如果程序内部作为多线程运行,我该如何纠正它?

以上是关于错误指针:解析标记时无法评估表达式的主要内容,如果未能解决你的问题,请参考以下文章

无法评估选定的表达式? - Eclipse 库调试错误

Thymeleaf 模板无法评估与模型相关的表达式

iVerilog 中的 MUX:无法绑定参数/无法评估 genvar 表达式错误

CXX0030 无法评估表达式

无法使用 Visual Studio 2013 调试托管代码(“无法评估表达式”错误 - 正在使用调试版本)(请注意,VS 2012 有效)

hashedmap和指向结构的指针:CXX0030:错误:无法计算表达式