Come ottenere il simbolo del separatore di file in C/C++ standard:/ o \?

 C Programming >> Programmazione C >  >> Tags >> File
Come ottenere il simbolo del separatore di file in C/C++ standard:/ o \?

Non sono sicuro di come farlo se non controllando ifdefs

inline char separator()
{
#ifdef _WIN32
    return '\\';
#else
    return '/';
#endif
}

o (come suggerito da PaperBirdMaster)

const char kPathSeparator =
#ifdef _WIN32
                            '\\';
#else
                            '/';
#endif

Se il tuo compilatore offre già funzionalità c++17, puoi usare std::experimental::filesystem::path::preferred_separator che dovrebbe restituire / o \ a seconda della tua piattaforma.

Vedi questo per ulteriori informazioni.


Questa domanda sta davvero alludendo a un problema molto più brutto.

Se ti interessa semplicemente UNIX rispetto a Winodws e ti interessa solo di directory e file, quello che hai già visto funzionerà (per lo più), ma il problema più generico di unire un nome di percorso nei suoi componenti è un problema molto più brutto. A seconda della piattaforma, un percorso può includere uno o più di:

  • Identificatore del volume
  • Elenco delle directory
  • Nome file
  • Substream all'interno del file
  • Numero di versione

Sebbene ci siano librerie di terze parti (come vari moduli CPAN Perl, Boost e altri) per questo, e ogni sistema operativo include funzioni di sistema per questo, non c'è nulla di integrato in C per questo e lo standard C++ ha ottenuto questa funzionalità solo (incorporando il modulo Boost) nel 2017.

Alcuni esempi di ciò che una tale funzione potrebbe dover gestire sono:

  • I sistemi UNIX e simili a UNIX utilizzano un elenco di stringhe separate da "/" caratteri, con una "/" iniziale per indicare un percorso assoluto (rispetto a un percorso relativo). In alcuni contesti (come NFS), potrebbe esserci anche un prefisso del nome host (con un delimitatore ":")
  • I sistemi operativi derivati ​​​​da DOS e DOS (Windows, OS/2 e altri) usano "\" come separatore di directory (con le API che accettano anche "/"), ma i percorsi possono anche essere preceduti da informazioni sul volume. Potrebbe essere una lettera di unità ("C:") o un nome di condivisione UNC ("\\MYSERVER\SHARE\"). Esistono prefissi aggiuntivi per rappresentare diversi tipi di server e suffissi per rappresentare flussi non predefiniti all'interno di un file.
  • I Mac (Mac OS classico, Carbon e alcune API Cocoa) usano ":" come separatore di directory, con il primo termine che è un nome di volume, non un nome di directory. I file Mac possono anche contenere flussi secondari ("fork"), a cui si accede tramite lo stesso nome utilizzando API per scopi speciali. Questo è particolarmente importante per il fork delle risorse , ampiamente utilizzato nei classici software per Mac.
  • Mac OS X, quando si utilizzano le API UNIX, generalmente fa ciò che fanno i sistemi simili a UNIX, ma possono anche rappresentare flussi secondari denominati ("fork") con il suffisso "." seguito dal nome del fork al nome del file.
  • Le ultime versioni di Cocoa (Mac OS X, iOS, ecc.) consigliano di utilizzare un'API basata su URL per rappresentare i file, a causa della complessità sempre crescente di questo problema. Pensa a cose come documenti basati su cloud e altri complicati file system in rete.
  • VMS è piuttosto complicato (https://web.archive.org/web/20160324205714/http://www.djesys.com/vms/freevms/mentor/vms_path.html), ma ha componenti che rappresentano un volume, percorso della directory, file e revisione del file.

Ce ne sono anche molti altri.

Vale la pena notare che la libreria del filesystem C++17 non copre tutte queste possibilità. Il std::filesystem::path consiste in un nome-root opzionale (un identificatore di volume), una directory-root opzionale (per identificare percorsi assoluti) e una sequenza di nomi di file separati da separatori di directory. Questo copre tutto ciò che potrebbe essere valido su piattaforme UNIX e la maggior parte dei casi d'uso per altre piattaforme, ma non è completo. Ad esempio, non ha alcun supporto per i flussi secondari (affidandosi al sistema operativo per mapparli in qualche modo su un nome di file, cosa che viene eseguita da Mac OS X, ma non da MacOS classico). Inoltre, non include il supporto per i numeri di versione dei file.

Vedi anche la voce di Wikipedia su Path e la classe C++17 std::filesystem::path

http://en.cppreference.com/w/cpp/filesystem

Ti consiglio di guardare cosa vuoi fare con il separatore di directory (estrai il nome di base, spezza un percorso in un elenco di directory, ecc.) E scrivi una funzione per farlo. Se stai usando C++17 (e sei certo che il tuo codice non sarà compilato da un compilatore C++ precedente a 17), puoi (probabilmente) usare il codice della libreria C++ standard per scrivere un'implementazione portatile di questa funzione. In caso contrario, quella funzione dovrà utilizzare #ifdef specifico della piattaforma s per ciascuna piattaforma che supporterai, utilizzando un #error se nessuna delle condizioni è soddisfatta, per costringerti ad aggiungere condizioni per piattaforme impreviste.

Oppure usa una libreria di terze parti (come Boost) che includa funzioni per tutto questo, se è accettabile.