【问题标题】:Access Violation while using _tcstok使用 _tcstok 时访问冲突
【发布时间】:2011-07-13 00:49:03
【问题描述】:

我正在尝试使用 _tcstok 标记文件中的行。我可以对线路进行一次标记,但是当我再次尝试对其进行标记时,我会遇到访问冲突。我觉得这与实际访问值有关,而是与位置有关。不过我不知道还能怎么做。

谢谢,

戴夫

附言我正在使用 TCHAR 和 _tcstok,因为文件是 UTF-8。

这是我得到的错误:

Testing.exe 中 0x63e866b4 (msvcr90d.dll) 的第一次机会异常:0xC0000005:访问冲突读取位置 0x0000006c。

vector<TCHAR> TabDelimitedSource::getNext() {
// Returns the next document (a given cell) from the file(s)
TCHAR row[256]; // Return NULL if no more documents/rows
vector<TCHAR> document;

try{
    //Read each line in the file, corresponding to and individual document
    buff_reader->getline(row,10000);
    }
catch (ifstream::failure e){
        ; // Ignore and fall through
    }

if (_tcslen(row)>0){
    this->current_row += 1;
    vector<TCHAR> cells;
      //Separate the line on tabs (id 'tab' document title 'tab' document body)
     TCHAR *  pch;
     pch = _tcstok(row,"\t");
     while (pch != NULL){
         cells.push_back(*pch);
         pch = _tcstok(NULL, "\t");
     }

    // Split the cell into individual words using the lucene analyzer
    try{
      //Separate the body by spaces
        TCHAR original_document ;
        original_document = (cells[column_holding_doc]);
        try{
            TCHAR * pc;
            pc = _tcstok((char*)original_document," ");
             while (pch != NULL){
                 document.push_back(*pc);
                pc = _tcstok(NULL, "\t");
             }

【问题讨论】:

  • 你为什么要投到char*而不是TCHAR*?另外,你把TCHAR 当作TCHAR* 对待,那肯定很糟糕。
  • 我去掉了一些选角等。还是一样的问题。
  • 显然不是。不用强制转换写出来,你应该就能找到错误了。
  • 摆脱了 char* 转换并得到了这个错误:'_tcstok' : cannot convert parameter 1 from 'TCHAR' to 'char ' 从整数类型转换为指针类型需要 reinterpret_cast, C风格转换或函数风格转换。我不明白为什么它会要求一个字符,因为我到处都在使用 TCHARs
  • 大卫:正确,这就是问题所在:-) 你不能把一个字符当作一个指针。我认为您的代码有很多问题,所以我不愿意提供建议,但是应该发生类似TCHAR * original_document = ... 的事情;但我认为即使是你的向量也不能满足你的要求......

标签: c++ visual-studio-2008 utf-8 access-violation


【解决方案1】:

首先,您的代码是 C 字符串操作和 C++ 容器的混合体。这只会让你陷入困境。理想情况下,您应该将该行标记为std::vector&lt;std::wstring&gt;

另外,您对 TCHAR 和 UTF-8 感到非常困惑。 TCHAR 是一种在 8 到 16 位之间“浮动”的字符类型,具体取决于编译时标志。 UTF-8 文件使用一到四个字节来表示每个字符。因此,您可能希望将文本保存为 std::wstring 对象,但您需要将 UTF-8 显式转换为 wstrings。

但是,如果您只是想让任何东西正常工作,请专注于您的标记化。您需要存储每个令牌的起始地址(作为TCHAR*),但您的向量是TCHARs 的向量。当您尝试使用令牌数据时,您将TCHARs 转换为TCHAR* 指针,访问冲突的结果不足为奇。你给的AV地址是0x0000006c,这是字符l的ASCII码。

  vector<TCHAR*> cells;
  ...
  cells.push_back(pch);

...然后...

    TCHAR *original_document = cells[column_holding_doc];
    TCHAR *pc = _tcstok(original_document," ");

【讨论】:

  • 谢谢。这是我第一次需要处理 UTF-8 文件,这让我大吃一惊。它比我认为的要复杂得多。
  • 非常感谢。我知道这确实不能解决问题,但是很高兴看到事情发生了,这样我就知道其他一切都在正常工作。我一定会开始着手将所有内容转移到 wstrings。
猜你喜欢
  • 2010-11-19
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多