如何更改文件的扩展名

时间:2018-06-28 03:48:14

标签: c

也有类似的问题,但我的问题更具体。我有一个C代码,当我使用RLE算法进行编码时,它将使用file.txt并返回file.txt.rle。我以相同的方式对此进行解码,并希望从file.txt.rle写入并返回file.txt。以下代码是我从file.txt转到file.txt.rle时使用的代码:

char name[NAME_SIZE];
if(sprintf(name, "%s.rle", argv[1]) >= sizeof(name)){
    fprintf(stderr, "Destination file name is too long\n");
}
while((o_fp = fopen(name, "wb")) == NULL){
    fprintf(stderr, "Can't create the file to be written\n");
      exit(1);
}

解码时如何完成将扩展名从file.txt.rle更改为file.txt?完整的代码无济于事,因为我将在解码已编码文件的代码中使用它。

注意:给定的格式始终为.txt.rle,返回文件应始终将其转换为.txt。

3 个答案:

答案 0 :(得分:0)

您可以使用以下方法简单地做到这一点:

  • strrchr查找字符串中最后一个句点在哪里,
  • strlen / malloc分配内存以存储新名称,
  • sprintf创建新名称。

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

/* this function will create a new name, replacing the existing extension
   by the given one.
   returned value should be `free()` after usage

   /!\ warning: 
        * validity of parameters is not tested
        * return of strdup and malloc are not tested.
   */
char *replace_ext(const char *org, const char *new_ext)
{
    char *ext;

    /* copy the original file */
    char *tmp = strdup(org);

    /* find last period in name */
    ext = strrchr(tmp , '.');

    /* if found, replace period with '\0', thus, we have a shorter string */
    if (ext) { *ext = '\0'; }

    /* compute the new name size: size of name w/o ext + size of ext + 1 
       for the final '\0' */
    size_t new_size = strlen(tmp) + strlen(new_ext) + 1;

    /* allocate memory for new name*/
    char *new_name = malloc(new_size);

    /* concatenate the two string */
    sprintf(new_name, "%s%s", tmp, new_ext);

    /* free tmp memory */
    free(tmp);

    /* return the new name */
    return new_name;
}

int main(void)
{
    int i;
    char *tests[] = { "test.ext", "test.two.ext", "test_no_ext", NULL};

    for (i = 0; tests[i]; ++i)
    {
        char *new_name = replace_ext(tests[i], ".foo");
        printf("%s --> %s\n", tests[i], new_name);
        free(new_name);
    }

    return 0;
}

答案 1 :(得分:0)

这是一个实现。 这里的魔术是由change_file_name(org, dest, size, ext)执行的,它检查名称​​ org 是否以 ext 结尾,在这种情况下,将名称复制到该位置。

希望这会有所帮助。

 /* Changes the name of the sys input file. */

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


bool change_file_name(const char * org, char * dest, size_t max_length, const char * file_ext)
{
    bool toret = false;
    const size_t name_length = strlen( org );
    const size_t ext_length = strlen( file_ext );
    const size_t new_name_size = name_length - ext_length;

    if ( name_length > ext_length
      && name_length < max_length
      && strcmp( org + new_name_size, file_ext ) == 0 )
    {
        strncpy( dest, org, name_length - ext_length );
        *( dest + new_name_size ) = 0;
        toret = true;
    }

    return toret;
}

void convert_file(const char * org, const char * dest)
{
    printf( "Processing file '%s' into '%s'\n", org, dest );
}

int main(int argc, char *argv[])
{
    const int NAME_SIZE = 1024;
    const char * rle_ext = ".rle";
    char new_name[NAME_SIZE];
    int toret = EXIT_SUCCESS;

    if ( argc == 2 ) {
        if ( change_file_name( argv[ 1 ], new_name, NAME_SIZE, rle_ext ) ) {
            printf( "The new name is: '%s'\n", new_name );
            convert_file( argv[ 1 ], new_name );
        } else {
            toret = EXIT_FAILURE;
            fprintf( stderr,
                     "Name results empty, is not ending in '%s' or is too large: '%s'\n",
                     rle_ext,
                     argv[ 1 ] );
        }
    } else {
        toret = EXIT_FAILURE;
        fprintf( stderr, "Usage: %s <file name>.txt.rle\n", argv[ 0 ] );
    }

    return toret;
}

答案 2 :(得分:0)

您可以使用strsep(继承至strtok)对输入文件名进行标记化,然后复制您感兴趣的部分并丢弃其余部分。

如果您输入的文件名始终是file.txt.rle格式,则可以使用以下代码。

char *name = malloc(sizeof(char) * NAME_SIZE);
if(sprintf(name, "%s.rle", argv[1]) >= sizeof(name)){
    fprintf(stderr, "Destination file name is too long\n");
}

char *token = NULL;
char *newfilename = malloc(sizeof(char) * (NAME_SIZE-4)); //strlen(".rle") = 4
uint8_t offset = 0;
memset(newfilename, 0, (NAME_SIZE-4));

while ((token = strsep(&name, ".")) != NULL) {
    if(strcmp(token, "rle") == 0) {
        break;
    }
    strncpy(newfilename+offset, token, strlen(token));
    offset += strlen(token);
    newfilename[offset] = '.';
    offset += 1;
}
newfilename[strlen(newfilename)-1] = '\0';