Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中,如何从完整路径(字符串)向文件名追加文本?_C - Fatal编程技术网

在C语言中,如何从完整路径(字符串)向文件名追加文本?

在C语言中,如何从完整路径(字符串)向文件名追加文本?,c,C,在C语言中,如何从完整路径(字符串)向文件名追加文本 例如: "/home/erikas/myfile.txt" would become "/home/erikas/myfile-generated.txt" "/home/erikas/myfile" would become "/home/erikas/myfile-generated" "/my.directory/my.super.file.txt" would become "/my.directory/my.super.file-g

在C语言中,如何从完整路径(字符串)向文件名追加文本

例如:

"/home/erikas/myfile.txt" would become "/home/erikas/myfile-generated.txt"
"/home/erikas/myfile" would become "/home/erikas/myfile-generated"
"/my.directory/my.super.file.txt" would become "/my.directory/my.super.file-generated.txt"

感觉就像我在试图重新发明一个轮子。这个问题有什么简单的解决办法吗?一个函数?

我刚刚为这个问题创建了自己的解决方案

请注意,此代码段将在完整路径上失败,如“myfile.txt”或“/home/my.user/”,但在我的情况下,我使用GTK选择文件,因此没有问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>

#ifdef _WIN32
#define SEPARATOR '\\'
#else
#define SEPARATOR '/'
#endif

#define GENERATED_APPEND_TEXT "-generated"

char *generate_output_fpath(char* fpath) {
    int last_separator_index = (int) (strrchr(fpath, SEPARATOR) - fpath);
    int last_dot_index = (int) (strrchr(fpath, '.') - fpath);

    char *new_fpath = malloc(strlen(fpath) + strlen(GENERATED_APPEND_TEXT) + 1); // +1 for \0

    if(new_fpath == NULL){
        return NULL; // malloc failed to allocate memory
    }

    // if dot does not exist or dot is before the last separator - file has no extension:
    if ( !last_dot_index || last_dot_index < last_separator_index) {
        new_fpath[0] = '\0'; //ensure it is empty
        strcat(new_fpath, fpath);
        strcat(new_fpath, GENERATED_APPEND_TEXT);
        return new_fpath;
    }

    int fpath_length = strlen(fpath);
    int append_text_length = strlen(GENERATED_APPEND_TEXT);

    int i = 0;
    int ii = 0;
    for (; i < last_dot_index; i++) {
        new_fpath[i] = fpath[i];
    }
    // We copied everything until dot. Now append:
    for (; ii < append_text_length; ii++) {
        new_fpath[i + ii] = GENERATED_APPEND_TEXT[ii];
    }
    // Now append extension with dot:
    for (; i < fpath_length; i++) {
        new_fpath[i + ii] = fpath[i];
    }
    return new_fpath;
}
请注意,可以在此处查看/测试完整示例:


欢迎提供有关代码优化的任何提示

我建议使用两个方便的函数:basename和dirname,而不是

也许这将帮助您获得一个经典的路径拆分案例,您需要首先确定
文件名
是否包含路径组件(例如,是否有
'/'
字符)。如果是这样,您可以使用
strrchr
'/'
获取指向最后一个
'/'
的指针并隔离文件名。然后问题切换到“我有分机吗?”。关于
'.
(通过健全性检查来保护“点/隐藏”文件(例如
.bashrc
))也是如此。如果有一个
并且它正在分隔
name.ext
,那么您就有一个指向
的指针,您可以将它隔离并保存
。ext
,将字符串追加并重新组合。或者,需要更改的规则是什么?在路径名的最后一个组件的最后一个点之前添加
-生成的
,或者在文件名组件中没有点时追加它?使用
/home/erikas/old.file.name
会发生什么?大概
/home/erikas/old.file generated.name
?在使用分配的内存之前,应该检查内存分配是否成功。如果分配失败,您可能只需返回NULL,并且调用代码应该检查NULL是否未返回。或者,您可以打印适当的错误消息并退出。这是否是一个好主意取决于它的使用环境。如果您正在编写一个命令行程序,它可能还可以;通常我会这么做。如果您正在编写GUI程序,可能出于多种原因,它不适合,只返回NULL更好。此外,我认为您的代码还不能处理
/home/some.user/plain_file
;它将在路径中的
之后添加
-生成的
,这不是您所说的您想要的。解决这个问题很容易;使用
int last_dot_index=(int)(strrchr(&fpath[last_separator_index],'))-fpath)。您可能还需要注意后面的斜杠(
/home/erikas/
)和普通文件名
erikas\u file
。这两种方法都可能给你的代码带来问题。更新以检查malloc是否没有失败。此外-这工作得非常好-我还使用GTK来选择文件,所以我可以证明它不会像“myfile.txt”或“/home/some.user/”那样。无论如何,谢谢-我会提到这一点。我误读(没有读)了测试的
| | last|u dot_index
部分-你是对的,它处理“last dot before last slash”条件(除非有尾随斜线,但这无论如何都是一个例外问题)。我为那个错误道歉。我无法知道您正在使用GTK获取原始文件名,因此只能获取没有尾随斜杠的绝对名称-尽管担心尾随斜杠充其量只是一种延伸。(即使说“我在使用GTK”也不会告诉我你会得到干净的名字。)
"/home/erikas/myfile.txt" would become "/home/erikas/myfile-generated.txt"
"/home/erikas/myfile" would become "/home/erikas/myfile-generated"