Come posso gestire questa concatenazione di stringhe in C in modo riutilizzabile

0

Ho scritto una piccola applicazione C che funziona su file, e ho scoperto che ho copiato e incollato questo codice attorno alle mie funzioni:

char fullpath[PATH_MAX];
fullpath[0] = '
char fullpath[PATH_MAX];
fullpath[0] = '%pre%';
strcat(fullpath, BASE_PATH);
strcat(fullpath, subdir);
strcat(fullpath, "/");
strcat(fullpath, filename);

// do something with fullpath...
'; strcat(fullpath, BASE_PATH); strcat(fullpath, subdir); strcat(fullpath, "/"); strcat(fullpath, filename); // do something with fullpath...

C'è un modo migliore? Il primo pensiero che mi viene in mente è quello di creare una macro, ma sono sicuro che questo è un problema comune in C, e mi chiedo come gli altri possano risolverlo.

    
posta tpaul 26.03.2014 - 18:58
fonte

3 risposte

2

Riutilizzabile per una funzione come quella che descrivi significa diverse cose:

  • Non presuppone che l'input sia valido.
  • Utilizza le impostazioni predefinite sane.
  • Impedisce il sovraccarico del buffer.
  • Restituisce qualche indicazione di successo o fallimento.

Nel tuo caso:

#define BASE_PATH "/path/to/wherever"
bool build_path(char *dest, size_t size, char *subdir, char *filename)
{
    // Don't assume the input is valid
    if ( (dest == NULL) || (size < 1) || (filename == NULL) ) {
        return false;
    }

    // Make no subdir work  (sane default behavior)
    if ( subdir == NULL ) {
        subdir = "";
    }

    // Prevent buffer overruns by using a safe formatting function
    size_t stored = snprintf(dest, size, BASE_PATH "/%s/%s", subdir, filename);

    // Returns success (true) if the path fit the buffer
    return ((stored+1) <= size);
}


char fullpath[PATH_MAX];
if ( ! build_path(fullpath, sizeof(fullpath), "foo/bar", "baz") ) {
   // Handle error
}
    
risposta data 02.06.2014 - 16:37
fonte
1

Che ne dici di passare l'indirizzo di fullpath , subdir e filename in una funzione e avere quella funzione per concatenare tutte le stringhe?

Qualcosa con l'effetto di:

void main(...)
{
    char fullpath[PATH_MAX];
    memset(fullpath, 0x00, PATH_MAX); //note: probably wrong syntax for memset
    ...
    ConcatPath(&fullpath, subdir, filename);
}

ConcatPath(char *fullpath, char *subdir, char *filename)
{
    strcat(fullpath, BASE_PATH);  //note need some casting magic here to reference
    strcat(fullpath, subdir);     // fullpath & other strings correctly.
    strcat(fullpath, "/");
    strcat(fullpath, filename);
}
    
risposta data 26.03.2014 - 19:08
fonte
0

Secondo me, come programmatore professionista, non devi scrivere un codice del genere. Tu devi scrivere la tua propria funzione di concatenazione dei percorsi, o usare quella fornita dalla piattaforma.

Se è Windows, dovresti usare la funzione _makepath . Per maggiore sicurezza, utilizza la funzione _makepath_s . Sarà più attento di quello che sei. Sono sicuro che Posix abbia qualcosa di simile.

Se devi scrivere il tuo, la semplice concatenazione non è abbastanza buona. È necessario controllare la corretta gestione dei delimitatori, la barra finale nelle directory, il periodo principale sulle estensioni, gli argomenti nulli e tutto il resto. La buona notizia è che se lo fai una volta fatto.

Nel caso più generale di concatenazione di stringhe, sei molto ostacolato dalla tua apparente decisione di attenersi a C piuttosto che a C ++. Raccomanderei nuovamente di scrivere la propria funzione con argomenti variabili ( vararg ) e utilizzando strcat_s() per sicurezza. Qualcosa come:

bool strcat_multi_s(char *destination, size_t maxlength, ...); // return false on overflow

Lascio la codifica come esercizio per il lettore.

    
risposta data 02.06.2014 - 12:53
fonte

Leggi altre domande sui tag