2013-03-31 22 views
5

Come verificare se un carattere è un carattere di fine riga in qualsiasi codifica in C?Controllo di un carattere come newline

Ho il compito di scrivere il mio programma wc. E se io uso solo se (s[i] == '\n') ha un'altra risposta che originale wc se lo chiamo a se stesso.
ecco il codice:

typedef struct 
{ 
    int newline; 
    int word; 
    int byte; 
} info; 

info count(int descr) 
{ 
    info kol; 
    kol.newline = 0; 
    kol.word = 0; 
    kol.byte = 0; 

    int len = 512; 
    char s[512]; 
    int n; 

    errno = 0; 
    int flag1 = 1; 
    int flag2 = 1; 
    while(n = read(descr, s, len)) 
    { 
     if(n == -1) 
      error("Error while reading.", errno); 

     errno = 0; 

     kol.byte+=n; 
     for(int i=0; i<n; i++) 
     { 
      if(flag1) 
      { 
       kol.newline++; 
       flag1 = 0; 
      } 

      if(isblank(s[i]) || s[i] == '\n') 
       flag2 = 1; 
      else 
      { 
       if(flag2) 
       { 
        kol.word++; 
        flag2 = 0; 
       } 
      } 
      if(s[i] == '\n') 
       flag1 = 1; 
     } 
    } 
    return kol; 
} 

Funziona bene per tutti i file di testo, ma quando io lo chiamo archiviare ho ottenuto dopo la compilazione sé does't dare la risposta wc dà.

+1

Intendi come ''\ n''? – Useless

+0

'\ n' funziona solo nella codifica ASCII. Intendo qualcosa come _isdigit() _ function – Taygrim

+0

Si chiama 'read (descr)', dove 'descr' è presumibilmente un descrittore di file. Come è stato aperto? E * come * il tuo output differisce da quello di 'wc', e su quale input? –

risposta

5

Il modo per verificare se un carattere s[i] è un carattere di nuova riga è semplicemente:

if (s[i] == '\n') 

Se state leggendo da un file che è stato aperto in modalità testo (compresi stdin), quindi qualunque sia la rappresentazione del sistema sottostante utilizza per segnare la fine di una linea sarà tradotto in un singolo '\n' carattere.

dici che stai cercando di scrivere il proprio programma wc, e confrontando per '\n' che stai ricevendo risultati diversi rispetto al sistema del wc. Non ci hai detto abbastanza per indovinare perché sta accadendo. Mostraci il tuo codice e dicci esattamente cosa sta succedendo.

Potresti incorrere in problemi se stai leggendo un file codificato in modo diverso, ad esempio provando a leggere un file di testo in formato Unix su un sistema Windows. Ma allora lo wc avrebbe lo stesso problema.

2

Ci sono diversi caratteri di nuova riga in ASCII e Unicode.

I più famosi sono \r e \n, da ASCII. Tecnicamente si tratta di ritorno a capo e avanzamento riga. Windows usa entrambi insieme \r\n (tecnicamente ritorno a capo significa passare alla colonna 0, l'avanzamento riga passa alla riga successiva, ma nulla di ciò che so obbedisce che in pratica), unix usa solo \n. Alcuni sistemi operativi (non comuni) utilizzano solo \r.

La maggior parte delle app si ferma qui e non ne risente. Quello che segue è più teorico.

Unicode complica le cose. U + 000A e U + 000B sono identici a \r e \n (stessa rappresentazione binaria in UTF-8). Poi c'è U + 0085 "riga successiva", U + 2028 "separatore di riga" e U + 2029 "separatore di paragrafo". Puoi anche controllare la scheda verticale (U + 000B) se vuoi controllare tutto. Vedi qui: http://en.wikipedia.org/wiki/Newline#Unicode

+0

In passato, alcuni dattilografi avevano bisogno sia di ritorno a capo * sia di avanzamento riga. –

+0

@xtofpernaud so che c'era un trucco con le stampanti molto vecchie per renderli caratteri di sovrastampa per disegnare immagini, ma mi riferivo davvero a tutto ciò che è ancora generalmente usato! – Dave

+0

\ r \ n viene ancora utilizzato, ad esempio tutti i protocolli basati su riga (ad esempio, SMTP, IMAP, POP3) e altri (ad esempio intestazioni HTTP) utilizzano \ r \ n come fine riga. E anche se invii i dati ad un terminale a basso livello, sono abbastanza sicuro che \ r è ancora necessario per tornare alla colonna 0. – Ale

1

Per quanto ne so, non esiste una funzione standard come le isXXXXX() quelle (la più vicina è quella isspace(), il che è vero anche per le altre condizioni (spazio, tab, modulo di alimentazione ...). Il semplice confronto con '\ n' dovrebbe risolvere il tuo problema, a seconda di quello che consideri un carattere di nuova riga, potresti anche voler controllare '\ r' (ritorno a capo). UNIX standard come separatore di riga è '\ n', Mac (prima di OS X) usato '\ r' (ora '\ n' è più comune, ma '\ r' a volte è ancora usato da alcune applicazioni, es. MS Office), DOS/Windows usa "\ r \ n" sequenza

+0

Mac OS X utilizza '\ n' e non' \ r'. –

+0

Non in tutte le applicazioni (vedi ad esempio file CSV esportati da Excel su OS X) – Ale

+0

@Ale è probabilmente più perché Microsoft non ha notato che era cambiato nell'aggiornamento ... in generale è '\ n' ora, ma non lo fa t importa perché dovresti sempre controllare * qualsiasi cosa *. Non si sa mai quando un utente ha copiato un file da un altro sistema operativo. – Dave

Problemi correlati