Question

J'utilise Linux GCC C99.

Je me demande quelle serait la meilleure technique. Pour changer une chaîne. J'utilise strstr ();

J'ai un nom de fichier appelé « file.vce » et je veux changer l'extension « file.wav ».

Est-ce la meilleure méthode:

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);

Merci beaucoup pour tout conseil,


Je l'ai modifié ma réponse en utilisant l'aide de vos suggestions. Pouvez-vous voir quoi que ce soit d'autre mal?

/** 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;
}
Était-ce utile?

La solution

Je ferais ce

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);

Vous devez faire la manipulation de pointeur dans tous les programmes c. Bien sûr, vous feriez un peu plus la vérification de mémoire tampon sur pistes etc., ou même utiliser le chemin des fonctions spécifiques.

Autres conseils

Il y a quelques problèmes avec:

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);

Il est le stockage que pour une seule chaîne, mais à la fin que vous tentez d'imprimer deux chaînes différentes.

La variable nommée new_file_name souligne en fait partie du même nom.

La VCE chaîne peut se produire n'importe où dans un nom de fichier, pas seulement une extension. Et si le nom de fichier a été srvce.vce?

Vous voulez sans doute trouver la dernière. caractère de la chaîne, puis vérifier si elle est suivie par l'extension prévue, puis remplacer cette extension. Et rappelez-vous que si vous faites cela en modifiant le tampon d'origine, vous ne serez pas en mesure d'imprimer l'ancienne chaîne par la suite.

Au lieu de chercher. ou VCE dont chacun peut apparaître plusieurs fois dans la chaîne, calculer la longueur de la chaîne et soustraire 3 au point de leur extension. Remplacez l'extension en place à l'aide 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);

Vous devez ajouter manuellement zéro terminaison à la fin de new_file_name parce strncpy() ne sera pas l'ajouter dans votre cas.

Il vient d'arriver que vous avez déjà octet nul à bon endroit, mais il ne peut pas être garantie dans toutes les situations il est donc une bonne habitude de faire des choses comme

new_file_name[3] = '\0';

après strncpy().

Aussi méfiez-vous cette chaîne "VCE" peut apparaître dans le nom de fichier.

Il y a quelques problèmes avec votre code. Voici une version différente, les changements commentés en ligne:

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);

Cela peut encore être améliorée, il ne vérifie pas qu'il ya assez de place pour inclure la nouvelle extension, par exemple. Mais il ne se termine la chaîne, de façon slighly plus naturel que piquer des caractères uniques.

Je me ennuie, et au lieu de pointer les problèmes dans le code original, je l'ai écrit moi-même. J'ai essayé de garder clairement à des fins instructives.

#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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top