Combiner de répertoire et de fichier chemin d'accès - C

Dans le cadre de l'apprentissage du C, j'ai écrit le code suivant pour combiner nom de répertoire avec un nom de fichier. Par exemple: combine("/home/user", "filename") entraînera /home/user/filename. Cette fonction devrait fonctionner sur toutes les plateformes (atleast sur toutes les distributions linux et windows 32 et 64 bits).

Voici le code.

const char* combine(const char* path1, const char* path2)
{
    if(path1 == NULL && path2 == NULL) {
        return NULL;
    }

    if(path2 == NULL || strlen(path2) == 0) return path1;
    if(path1 == NULL || strlen(path1) == 0) return path2;

    char* directory_separator = "";
#ifdef WIN32
    directory_separator = "\\";
#else 
    directory_separator = "/";
#endif

    char p1[strlen(path1)];                    //(1)
    strcpy(p1, path1);                         //(2) 
    char *last_char = &p1[strlen(path1) - 1];  //(3)

    char *combined = malloc(strlen(path1) + 1 + strlen(path2));
    int append_directory_separator = 0;
    if(strcmp(last_char, directory_separator) != 0) {
        append_directory_separator = 1;
    }
    strcpy(combined, path1);
    if(append_directory_separator)
        strcat(combined, directory_separator);
    strcat(combined, path2);
    return combined;
}

J'ai les questions suivantes concernant le code ci-dessus.

  1. Examiner les lignes, numérotées 1,2,3. Tous ces 3 lignes sont pour obtenir le dernier élément de la chaîne. On dirait que je suis en train d'écrire plus de code pour une si petite chose. Quelle est la bonne méthode pour obtenir le dernier élément de la char* chaîne.
  2. De retourner le résultat, je suis l'allocation d'une nouvelle chaîne à l'aide de malloc. Je ne suis pas sûr que ce soit la bonne façon de le faire. L'appelant devrait libérer le résultat? Comment puis-je indiquer à l'appelant qu'il a de libre que le résultat? Est-il réduit les risques d'erreurs de méthode disponible?
  3. Comment évaluez-vous le code (Faible, Moyen, Bon)? Quelles sont les zones qui peuvent être imrpoved?

Toute aide serait super.

Modifier

Fixe toutes les questions discutées et mises en œuvre les modifications proposées. Voici le code mis à jour.

void combine(char* destination, const char* path1, const char* path2)
{
    if(path1 == NULL && path2 == NULL) {
        strcpy(destination, "");;
    }
    else if(path2 == NULL || strlen(path2) == 0) {
        strcpy(destination, path1);
    }
    else if(path1 == NULL || strlen(path1) == 0) {
        strcpy(destination, path2);
    } 
    else {
        char directory_separator[] = "/";
#ifdef WIN32
        directory_separator[0] = '\\';
#endif
        const char *last_char = path1;
        while(*last_char != '
void combine(char* destination, const char* path1, const char* path2)
{
if(path1 == NULL && path2 == NULL) {
strcpy(destination, "");;
}
else if(path2 == NULL || strlen(path2) == 0) {
strcpy(destination, path1);
}
else if(path1 == NULL || strlen(path1) == 0) {
strcpy(destination, path2);
} 
else {
char directory_separator[] = "/";
#ifdef WIN32
directory_separator[0] = '\\';
#endif
const char *last_char = path1;
while(*last_char != '\0')
last_char++;        
int append_directory_separator = 0;
if(strcmp(last_char, directory_separator) != 0) {
append_directory_separator = 1;
}
strcpy(destination, path1);
if(append_directory_separator)
strcat(destination, directory_separator);
strcat(destination, path2);
}
}
'
) last_char++; int append_directory_separator = 0; if(strcmp(last_char, directory_separator) != 0) { append_directory_separator = 1; } strcpy(destination, path1); if(append_directory_separator) strcat(destination, directory_separator); strcat(destination, path2); } }

Dans la nouvelle version, l'appelant a allouer suffisamment de mémoire tampon et de l'envoyer à combine méthode. Cela évite l'utilisation de malloc et free question. Ici est l'utilisation

int main(int argc, char **argv)
{
    const char *d = "/usr/bin";
    const char* f = "filename.txt";
    char result[strlen(d) + strlen(f) + 2];
    combine(result, d, f);
    printf("%s\n", result);
    return 0;
}

Des suggestions d'améliorations?

OriginalL'auteur Navaneeth K N | 2010-06-29