提问人:Rakesh Solanki 提问时间:5/10/2023 更新时间:5/10/2023 访问量:34
strtok 在视觉对象 C 中给出访问冲突写入位置错误 [duplicate]
strtok giving Access violation writing location error in visual C [duplicate]
问:
我正在使用和理解 strtok 一段时间,但这次它给出了意想不到的错误。我不知道出了什么问题。请帮忙。我在 Windows 10 上使用 Visual Studio。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
char* filepath = "C:\\Users\\RAKESH\\source\\repos\\TESTING\\log.c";
char* filename = strtok(filepath, "\\");
while (filename != NULL)
{
filename = strtok(NULL, "\\");
}
printf("%s\n", filename);
return 0;
}
答:
0赞
Rakesh Solanki
5/10/2023
#1
在我发布这个问题之前,我直观地发现了错误。实际上,strtok 需要操作 char 数组,因此它需要 char 数组中的读写内存空间才能做到这一点,因此它不能处理通常存储在只读内存中的字符串文本。所以解决方案是:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FILENAME_MAX 260
int main(int argc, char* argv[])
{
char* filepath = (char*)malloc(FILENAME_MAX * sizeof(char));
strcpy(filepath, "C:\\Users\\RAKESH\\source\\repos\\TESTING\\log.c");
char* filename = strtok(filepath, "\\");
while (filename != NULL)
{
filename = strtok(NULL, "\\");
}
printf("%s\n", filename);
free(filepath);
return 0;
}
注意:此代码不提供文件名,但返回 NULL 作为文件名,因此要获取实际文件名,需要在 while 循环中更改以下代码:
while (filename != NULL)
{
if (strstr(filename, ".") == NULL)
filename = strtok(NULL, "\\");
else
break;
}
评论
2赞
Ian Abbott
5/10/2023
另一种选择是创建一个初始化的数组,而不是指向 : 的指针。现在,字符串文本仅用于初始化数组,其大小是从初始值设定项自动确定的。filepath
char
char
char filepath[] = "C:\\Users\\RAKESH\\source\\repos\\TESTING\\log.c";
filepath
1赞
Eugene Sh.
5/10/2023
因此,它无法与没有自己记忆的文字一起使用。- 它有自己的内存,但修改它会导致调用未定义的行为。将其视为只读。
1赞
Jonathan Leffler
5/10/2023
考虑找到最右边的反斜杠的优点。当心给定驱动器上的尾部反斜杠和根目录。strrchr(filepath, '\\')
1赞
chux - Reinstate Monica
5/10/2023
@Rakesh Solanki, 另类::strcspn()
size_t filename_offset(const char *path) { const char *path_original = path; size_t offset; while (path[(offset = strcspn(path, "/\\"))] != '\0') { path += offset + 1; } return (size_t) (path - path_original); } int main() { char* filepath = "C:\\Users\\RAKESH\\source\\repos\\TESTING\\log.c"; int offset = (int) filename_offset(filepath); printf("'%s'\n", filepath + offset); filepath = "just_slash\\"; offset = (int) filename_offset(filepath); printf("'%s'\n", filepath + offset); }
1赞
chux - Reinstate Monica
5/10/2023
@Rakesh Solanki,字符串文字肯定不在只读内存中。你的第一个代码可能已经起作用了。然而,写入字符串文字内存是 UB - 不要这样做。
评论