2016-01-05 23 views
8

Sto leggendo un file di testo ASCII. È definito dalla dimensione di ogni campo, in byte. Per esempio. Ogni riga è composta da 10 byte per una stringa, 8 byte per un valore in virgola mobile, 5 byte per un numero intero e così via.C++ ottiene la dimensione (in byte) di EOL

Il mio problema è leggere il carattere di nuova riga, che ha una dimensione variabile a seconda del sistema operativo (di solito 2 byte per Windows e 1 byte per Linux credo).

Come posso ottenere la dimensione del carattere EOL in C++?

Per esempio, in python che posso fare:

len(os.linesep) 
+4

Se si sta aprendo il file in modalità testo, le nuove linee dovrebbero sempre essere ''\ n'', qualunque sia la fine della linea nativa. Hai veramente bisogno di conoscere la dimensione della stringa EOL nativa? – Badministrator

+0

È garantito che il file sia stato salvato nello stesso SO di quello in cui viene eseguito il codice che lo legge? Se sì, basta aprire il file in modalità testo (non binario). – dxiv

risposta

0

Non sono sicuro che la traduzione si verifica quando si pensa che è. Guardate il seguente codice:

ostringstream buf; 
buf<< std::endl; 
string s = buf.str(); 
int i = strlen(s.c_str()); 

Dopo questo, in esecuzione su Windows, i == 1. Così la fine della definizione della linea in STD è 1 carattere. Come altri hanno commentato, questo è il carattere "\ n".

+0

Questo codice è errato perché CRT lib non gira '\ n' in' \ r \ n' per i buffer in memoria, ma lo fa per file e console. –

+0

Qui stai dimostrando il problema con cui mi trovo. C++ convertirà "\ n" nel carattere specifico di OS durante la scrittura su un file/console, ma non su un buffer. – jramm

+0

@jramm Non penso che tu abbia già spiegato abbastanza bene il tuo problema. '\ n' non ha bisogno di (e di fatto non potrebbe) essere codificato di sorta quando scritto in un buffer. Ma quando scriverete quel buffer su un file aperto in * text * mode, il '\ n' sarà tradotto automaticamente in qualunque cosa la piattaforma imponga. Quindi se apri lo stesso file in modalità _text_ e lo rileggi, la sequenza di nuova riga verrà tradotta in '\ n'. Quindi, almeno per me, non è chiaro il motivo per cui è necessario conoscere la codifica di '\ n' nel file su disco. – dxiv

1

Il modo onorato di fare questo è leggere una riga.

Ora l'ultimo carattere deve essere \n. Spogliarlo Quindi, guarda il personaggio precedente. Sarà o \r o qualcos'altro. Se è \r, barralo.

Per i file di testo [ascii] di Windows, non ci sono altre possibilità.

Questo funziona anche se il file è misto (ad esempio alcune righe sono \r\n e alcune sono solo \n).

È possibile farlo provvisoriamente su poche righe, solo per assicurarsi che non si tratti di qualcosa di strano.

Dopo questo, ora sai cosa aspettarti per la maggior parte del file. Ma il metodo strip è il modo generale affidabile. Su Windows, potresti avere un file importato da Unix (o viceversa).

+0

Mezzo pisolino, ma è difficile "leggere una riga" senza sapere in anticipo quale sia il terminatore di riga. Ad esempio, la tua ricetta fallisce per i terminatori di riga '\ r', e anche per le righe vuote consecutive salvate come' \ r \ n \ n \ n' che sono state avvistate in windows-land. – dxiv

+1

@dxiv Il metodo funziona contro '\ r \ n \ n \ n' (ad esempio' \ r \ n \ n \ n') - questa è solo la modalità mista come ho detto [consecutivo non è un problema]. Non ho visto un file '\ r' solo in 20+ anni [se mai, e ho convertito migliaia di file].Non leggibile da molti programmi poiché ora presuppongono [almeno] una nuova riga. Prova DOS 'type file' su uno ;-) Non penso che nemmeno MS li supporti più. '\ r' è valido [come non terminatore] al _inizio di una riga (ad esempio, output di progresso acquisito). Ne ho visto molto di più (ad es. '\ Rpgm è finito al 56% \ rpgm è finito al 57 %') –

+0

@CraigEstey - I file Mac di vecchia scuola sono solo \ r. Vedi wikipedia: https://en.wikipedia.org/wiki/Newline – user3690202