2015-06-26 13 views
6

Questa riflessione deriva da una discussione su un problema pratico Replacing multiple new lines in a file with just one. Si è verificato qualcosa di sbagliato durante l'utilizzo di un terminale cygwin in esecuzione su un computer Windows 8.1.È necessario scrivere un "portatile" se (c == ' n') per elaborare i file multipiattaforma?

Poiché il terminatore end-of-line sarebbe stato diverso, come \n, \r o \r\n, è necessario scrivere un "portatile" if(c=='\n') per farlo funzionare bene su Linux, Windows e OS X? Oppure, la best practice è solo per convertire il file con comandi/strumenti?

#include <stdio.h> 
    int main() 
    { 
     FILE * pFile; 
     int c; 
     int n = 0; 
     pFile=fopen ("myfile.txt","r"); 
     if (pFile==NULL) perror ("Error opening file"); 
     else 
     { 
     do { 
      c = fgetc (pFile); 
      if (c == '\n') n++; // will it work fine under different platform? 
     } while (c != EOF); 
     fclose (pFile); 
     printf ("The file contains %d lines.\n",n); 
     } 
     return 0; 
    } 

Update1:

CRT sarà sempre convertire i fine riga in '\ n'?

+1

CRT convertirà sempre le terminazioni di riga in ''\ n'', quindi se leggi il file come testo sarà automaticamente portatile. A meno che non vogliate leggere un file da qualsiasi piattaforma con qualsiasi tipo di fine linea –

+0

@ LưuVĩnhPhúc Grazie.E se stai cercando di leggere un file (che è stato creato su Windows) sotto Linux, la cosa migliore è riscrivere 'if (c == '\ n')', o semplicemente convertire il file con comandi/strumenti? –

+0

@ LưuVĩnhPhúc sbagliato (in generale). Le terminazioni di riga vengono tradotte solo su piattaforme Microsoft, se il file/stream viene aperto in "modalità ASCII" (che solo * esiste * su piattaforme Microsoft) – joop

risposta

4

Se un file di input viene aperto in modalità binaria (il carattere 'b' nella stringa di modalità), è necessario preoccuparsi dell'eventuale presenza di '\r' prima di '\n'.

Se il file non viene aperto in modalità binaria (e anche non legge usando le funzioni binarie come fread()) allora non è necessario preoccuparsi della presenza di '\r' prima '\n' perché saranno gestiti prima che l'ingresso perviene il tuo codice - tramite una funzione di sistema pertinente (ad es. driver di dispositivo che legge l'input da disco o da stdin) o dall'implementazione delle funzioni che usi per leggere l'input dal file.

Se si trasferiscono file tra sistemi (ad esempio scrivendo il file sotto linux e trasferendolo in un sistema Windows, dove un programma tenta di leggerlo) allora si hanno opzioni;

  • scrivere e leggere il file in modalità non binaria ed eseguire una traduzione rilevante del file durante il trasferimento tra i sistemi. Se si utilizza ftp, è possibile gestirlo trasferendo il file utilizzando la modalità testo anziché la modalità binaria. Se il file viene trasferito in modalità binaria, sarà necessario eseguire il file tramite dos2unix (se si trasferisce il file in Unix) o tramite unix2dos (andando nell'altro senso).
  • Effettua tutto il tuo I/O in modalità binaria, trasferiscile tra i sistemi utilizzando la modalità binaria e non li legge mai in modalità non binaria. Tra le altre cose, questo ti dà il controllo esplicito su quali dati sono nel file.
  • Scrivi il tuo file in modalità testo, trasferisci il file come meglio credi. Quindi leggi solo in modalità binaria e, quando il tuo codice di lettura incontra una coppia \r\n, rilascia il carattere '\r'.

L'ultima è senza dubbio il più robusto - il codice di scrittura potrebbe includere \r prima \n caratteri, o non potrebbe, ma il codice di lettura ignora semplicemente qualsiasi '\r' personaggi che incontra prima di un carattere '\n'. Tale codice probabilmente riuscirà anche a far sì che i file vengano modificati a mano (ad esempio con un editor di testo) che potrebbe essere configurato separatamente per inserire o rimuovere \r e \n prima di essere letto.

+0

+1 queste sono le opzioni. Farei il trasferimento binario completamente controllato: la quantità di lavoro è la stessa, ma con meno fattori coinvolti – slezica

+0

Forse. Ma l'OP non ha fornito informazioni sufficienti per aiutare a scegliere tra le opzioni. – Peter

+0

@Peter Grazie per l'analisi dettagliata. Aiuta davvero. –

Problemi correlati