简体   繁体   中英

C: creating new file extensions based on a filename

I would like to name output files based on a base filename with a different extension. In C psuedo-code:

a_file = fopen(filename + ".dt1","wt");
b_file = fopen(filename + ".dt2","wt");
c_file = fopen(filename + ".dt3","wt");

I tried following this example using strncat , but my program keeps appending to filename .

f1=fopen(strcat(filename,".dt1"),"wt");
f2=fopen(strcat(filename,".dt2"),"wt");
f3=fopen(strcat(filename,".dt3"),"wt");

This outputs:

filename.dt1
filename.dt1.dt2
filename.dt1.dt2.dt3

I need the end result to look like:

filename.dt1
filename.dt2
filename.dt3

Your code is working as expected considering that strcat appends the extension to the given string. You're using only one string, and so the extensions get stacked upon one another.

Here's one way to do this, amending your posted code which uses a single string for filename :

size_t len = strlen(filename);
f1 = fopen(strcat(filename, ".dt1"), "wt");
filename[len] = '\0';
f2 = fopen(strcat(filename, ".dt2"), "wt");
filename[len] = '\0';
f3 = fopen(strcat(filename, ".dt3"), "wt");

Setting this index to \\0 effectively truncates filename back to the original string between calls.

Note that filename must be large enough to contain the appended extensions - room for 4 additional characters - and that by doing this you'll lose the intermediate file names after opening each file.

Alternately, if your extensions will only differ in the last character:

size_t len = 0;
f1 = fopen(strcat(filename, ".dt1"), "wt");
len = strlen(filename);
filename[len - 1] = '2';
f2 = fopen(filename), "wt");
filename[len - 1] = '3';
f3 = fopen(filename, "wt");

The same caveats as above apply.

That's because strcat writes directly to the buffer of the first string.

The easiest way is probably to use snprintf to join the two strings together:

snprintf(filename_a, n+4, "%s.dt1", filename);
snprintf(filename_b, n+4, "%s.dt2", filename);
snprintf(filename_c, n+4, "%s.dt3", filename);

Here, filename is of length n (including the trailing \\0 ), and filename_a , filename_b and filename_c are buffers of length at least n+4 .

(You could also use sprintf , but it's always good to be careful.)

Pretty much reasonable output of yours I would say:

char * strcat ( char * destination, const char * source );

Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a new null-character is appended at the end of the new string formed by the concatenation of both in destination.

So, character array pointed to by filename is both returned from strcat and gets modified with concatenation result.

Very easy fix is to remember filename length before modification and then:

filename[filename_length_before_modification] = '\0';

this will effectively cut appended extension and get you back to starting point

Kind of a pain with standard C libs, but this is the way I would do it.

    char *fn = malloc(strlen(filename+5)); // Allocate a string with enough space
                                           // for the extensions.

    sprintf(fn, "%s.dt1", filename);       // Copy the name with extensions into fn.
    a_file = fopen(fn,"wt");               //
    sprintf(fn, "%s.dt2", filename);       //
    b_file = fopen(fn,"wt");               //
    sprintf(fn, "%s.dt3", filename);       //
    c_file = fopen(fn,"wt");               //

    free(fn); // Free the memory gained from malloc.

A more efficent way. It only copies the extension each time. It can be made even more efficient if we assume that only the last character changes (see pb2q's second solution ).

(Untested, off by one likely)

size_t len = strlen(filename);
char *buf = malloc(len+4); // Allocate a string with enough space for the
                           // extensions.
strcpy(buf, filename);
char *ext = buf+len // Get a pointer to where the extension starts.

strcpy(ext, ".dt1");             // Copy the name with extensions into fn.
FILE *a_file = fopen(buf, "wt"); //
strcpy(ext, ".dt2");             // 
FILE *b_file = fopen(buf, "wt"); //
strcpy(ext, ".dt3");             // 
FILE *c_file = fopen(buf, "wt"); //

free(buf); // Free the memory gained from malloc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM