Domanda

Sto usando Linux GCC C99.

Mi chiedo quale sarebbe la migliore tecnica. Per modificare una stringa. Sto usando strstr ();

Ho un nome di file chiamato "file.vce" e voglio cambiare l'estensione a "file.wav".

E 'questo il metodo migliore:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);

Molte grazie per qualsiasi consiglio,


Ho modificato la mia risposta utilizzando utilizzando i vostri suggerimenti. Riesci a vedere qualcosa che non va?

/** Replace the file extension .vce with .wav */
void replace_file_extension(char *file_name)
{
    char *p_extension;

    /** Find the extension .vce */
    p_extension = strrchr(file_name, '.');
    if(p_extension)
    {
        strcpy(++p_extension, "wav");
    }
    else
    {
        /** Filename did not have the .vce extension */
        /** Display debug information */
    }
}

int main(void)
{
    char filename[80] = "filename.vce";

    replace_file_extension(filename);

    printf("filename: %s\n", filename);
    return 0;
}
È stato utile?

Soluzione

Vorrei farlo

char file_name[80] = "filename.vce";
char *pExt;

pExt = strrchr(file_name, ".");
if( pExt )
  strcpy(++pExt, "wav");
else
{
 // hey no extension
}
printf("file name: %s\n", file_name);

Hai bisogno di fare la manipolazione dei puntatori in ogni programma c. Naturalmente si farebbe ancora un po 'il controllo di buffer di oltre corre ecc o anche di utilizzare il percorso di funzioni specifiche.

Altri suggerimenti

Ci sono alcuni problemi con:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;
new_file_name = strstr(file_name, "vce");
strncpy(new_file_name, "wav", 3);
printf("new file name: %s\n", new_file_name);
printf("file name: %s\n", file_name);

C'è solo memoria per una stringa, ma alla fine si tenta di stampare due stringhe differenti.

Il nome new_file_name variabile in realtà punta a parte lo stesso nome.

Il VCE stringa potrebbe verificarsi in qualsiasi punto all'interno di un nome di file, non solo un l'estensione. Che cosa succede se il nome del file è stato srvce.vce?

Probabilmente si desidera trovare l'ultima. carattere nella stringa, quindi verificare se è seguito dall'estensione prevista, e quindi sostituire tale estensione. E ricordate che se si esegue questa operazione modificando il buffer originale, non sarà in grado di stampare il vecchio stringa di seguito.

Invece di cercare. o vce ciascuno dei quali può apparire più volte nella stringa, calcolare la lunghezza della stringa e sottrarre 3 punti per estensione. Sostituire l'estensione sul posto utilizzando strncpy.

size_t length;
char* pextension;
char file_name[80] = "filename.vce";
printf("file name: %s\n", file_name);    
length = strlen(file_name);
pextension = file_name + length - 3;
strncpy(pextension, "wav", 3);
printf("new file name: %s\n", file_name);

È necessario aggiungere manualmente zero terminatore alla fine del new_file_name perché strncpy() non aggiungerà nel tuo caso.

E 'appena successo che hai già pari a zero byte al posto giusto, ma non può essere garantita in tutte le situazioni, quindi è una buona abitudine di fare cose come

new_file_name[3] = '\0';

dopo strncpy().

attenti anche quella stringa "vce" potrebbe apparire all'interno del file.

Ci sono alcuni problemi con il codice. Ecco un approccio diverso, con le modifiche commentato in linea:

char file_name[80] = "filename.vce";
char *new_file_name = NULL;

printf("old file name: '%s'\n", file_name);
/* Use strrstr(), to find the last occurance, and include the period. */
new_file_name = strrstr(file_name, ".vce");
if(new_file_name != NULL)
{
  /* Use plain strcpy() to make sure the terminator gets there.
   * Don't forget the period.
  */
  strcpy(new_file_name, ".wav");
}
printf("new file name: '%s'\n", file_name);

Questo può ancora essere migliorato, non controlla che ci sia abbastanza spazio per includere la nuova estensione, per esempio. Ma lo fa terminare la stringa, in un modo leggermente più naturale che frugando a singoli caratteri.

Mi annoio, e invece di indicare i problemi nel codice originale, ho scritto il mio. Ho cercato di mantenere in chiaro per scopi istruttivi.

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


/* Replace the last suffix in a filename with a new suffix. Copy the new
   name to a new string, allocated with malloc. Return new string. 
   Caller MUST free new string.

   If old name has no suffix, a period and the new suffix is appended
   to it. The new suffix MUST include a period it one is desired.

   Slashes are interepreted to separate directories in the filename.
   Suffixes are only looked after the last slash, if any.

   */
char *replace_filename_suffix(const char *pathname, const char *new_suffix)
{
    size_t new_size;
    size_t pathname_len;
    size_t suffix_len;
    size_t before_suffix;
    char *last_slash;
    char *last_period;
    char *new_name;

    /* Allocate enough memory for the resulting string. We allocate enough
       for the worst case, for simplicity. */
    pathname_len = strlen(pathname);
    suffix_len = strlen(new_suffix);
    new_size = pathname_len + suffix_len + 1;
    new_name = malloc(new_size);
    if (new_name == NULL)
        return NULL;

    /* Compute the number of characters to copy from the old name. */
    last_slash = strrchr(pathname, '/');
    last_period = strrchr(pathname, '.');
    if (last_period && (!last_slash || last_period > last_slash))
        before_suffix = last_period - pathname;
    else
        before_suffix = pathname_len;

    /* Copy over the stuff before the old suffix. Then append a period
       and the new suffix. */
#if USE_SPRINTF
    /* This uses snprintf, which is how I would normally do this. The
       %.*s formatting directive is used to copy a specific amount
       of text from pathname. Note that this has the theoretical
       problem with filenames larger than will fit into an integer. */
    snprintf(new_name, new_size, "%.*s%s", (int) before_suffix, pathname,
             new_suffix);
#else
    /* This uses memcpy and strcpy, to demonstrate how they might be
       used instead. Much C string processing needs to be done with
       these low-level tools. */
    memcpy(new_name, pathname, before_suffix);
    strcpy(new_name + before_suffix, new_suffix);
#endif

    /* All done. */
    return new_name;
}


int main(int argc, char **argv)
{
    int i;
    char *new_name;

    for (i = 1; i + 1 < argc; ++i) {
        new_name = replace_filename_suffix(argv[i], argv[i+1]);
        if (new_name == NULL) {
            perror("replace_filename_suffix");
            return EXIT_FAILURE;
        }
        printf("original: %s\nsuffix: %s\nnew name: %s\n",
               argv[i], argv[i+1], new_name);
        free(new_name);
    }
    return 0;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top