C语言中strtok()与strcat()配合使用触发非法硬件指令问题及路径拆分需求求助
解决C语言路径拆分的崩溃问题
嘿,我来帮你搞定这个问题!你的代码里有几个关键bug导致了崩溃,咱们一个个拆解清楚:
你的代码里的核心问题
base数组的大小完全错误:sizeof(file)得到的是指针的字节数(64位系统里是8字节),不是传入路径字符串的长度!这就导致base只有可怜的8个字节,strcat拼接路径时直接越界写内存,触发非法指令崩溃。- 修改了只读内存:
strtok会直接修改传入的字符串,但argv[1]指向的是程序启动时系统分配的只读内存区域,强行修改会触发未定义行为,这也是崩溃的一大原因。 - 最后拿不到文件名:循环结束后
tok已经变成NULL了,你打印Last element时输出的是空或者乱码,得在循环里把最后一次的tok存下来才行。
更简洁可靠的解决方案
其实拆分路径不用strtok循环这么麻烦,用strrchr直接找最后一个/的位置就搞定了,还能处理各种边界情况(比如根目录下的文件、没有斜杠的文件名)。下面是修正后的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { // 先检查参数是否合法 if (argc < 2) { fprintf(stderr, "用法: %s <文件路径>\n", argv[0]); return EXIT_FAILURE; } // 把只读的argv路径复制到可写缓冲区,避免修改只读内存 char *file = strdup(argv[1]); if (file == NULL) { perror("内存分配失败"); return EXIT_FAILURE; } char *last_slash = strrchr(file, '/'); char *parent_dir = file; char *filename = NULL; if (last_slash != NULL) { // 把最后一个'/'换成结束符,拆分出父目录 *last_slash = '\0'; filename = last_slash + 1; // 特殊情况:如果路径是"/file.txt",父目录应该是"/" if (strlen(parent_dir) == 0) { parent_dir = "/"; } } else { // 没有斜杠,说明是当前目录下的文件,父目录用"."表示 parent_dir = "."; filename = file; } printf("Base folder: %s\n", parent_dir); printf("Last element: %s\n", filename); // 释放之前分配的内存 free(file); return EXIT_SUCCESS; }
代码说明
- 参数检查:先判断用户有没有传入路径参数,避免
argv[1]为空导致崩溃。 - 复制路径到可写缓冲区:用
strdup把argv[1]的内容复制到可写内存,避免修改只读区域。 - 用
strrchr找最后一个斜杠:这个函数能快速定位路径里最后一个/,比循环strtok高效得多。 - 处理边界情况:比如路径是
/file.txt时,父目录应该是/;如果没有斜杠(比如file.txt),父目录就是当前目录.。
测试你给的输入./getlast /this/is/some/path/file.txt,就能得到你想要的预期输出啦!
内容的提问来源于stack exchange,提问作者Sisyffe
相关产品推荐
相关产品推荐

