也有类似的问题,但我的问题更具体。我有一个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。
答案 0 :(得分:0)
您可以使用以下方法简单地做到这一点:
#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';