调用strtok()时访问冲突; C ++

时间:2014-08-30 12:24:50

标签: c++ strtok

我在使用这段代码时遇到了麻烦:

char KernelFS::doesExist(char* fname){
    char part;
    char name[8];
    char ext[3];

    char* token;

    token = strtok(fname, "\\");
    strncpy(&part, token, 1);

    token = strtok(fname, "\\");
    strncpy(name, token, 8);

    token = strtok(fname, "\\");
    strncpy(ext, token, 3);

    return 0;
}

当我在第一次调用strtok(...)时运行它时编译并中断 - 访问冲突写入位置... 不明白为什么:(

我用以下方法调用此函数:

KernelFS :: doesExist( “X:\ TEST.EXE”);

重点是将fname char数组分成3个数组; 一个用于分区的名称, 一个用于文件名, 一个用于文件扩展名;

感谢您的帮助! :)

2 个答案:

答案 0 :(得分:4)

在你的例子中:

KernelFS::doesExist("X:\test.exe");

"X:\test.exe"实际上属于const char*类型,您无法对其进行修改。原始字符串文字在受保护的内存区域内分配,因此遇到了错误。

  

char * strtok char * str,const char * delimiters);

     

str -   请注意,此字符串通过分解为较小的字符串(标记)而已修改。   或者,可以指定空指针,在这种情况下,函数继续扫描先前成功调用函数的位置。

如果你真的想使用<cstring>库(不建议使用),你应该在堆栈上分配你的字符串而不是从程序符号中获取它。区域。

char path[] = { "X:\\test.exe" };
KernelFS::doesExist(path);

但是,建议您切换到<string>库。

答案 1 :(得分:1)

我建议进行以下修改:

char KernelFS::doesExist(char* fname)
{
    // Our variables.
    char part[2];
    char name[9];
    char ext[4];        
    char* token;

    // Initialize variables.
    memset(part, '\0', 2);
    memset(name, '\0', 9);
    memset(ext, '\0', 4);

    // If we receive an invalid string:
    if (fname == NULL)
        return -1; // Return error.

    // Process.
    if ((token = strtok(fname, "\\")) != NULL)
        strncpy(part, token, 1);
    if ((token = strtok(fname, "\\")) != NULL)
        strncpy(name, token, 8);
    if ((token = strtok(fname, "\\")) != NULL)
        strncpy(ext, token, 3);

    // If we retrieved the 3 variables:
    if (strlen(part) > 0 && strlen(name) > 0 && strlen(ext) > 0)
    {
        // Do something with part, name and ext here.
    }

    // Return success.
    return 0;
}

正如Piotr S.所说,请注意使用有效的char * (不是const char *或其他任何内容)调用此函数。