2016-04-14 31 views
5

Questo pezzo di codice è un po 'strano per i miei gusti. Per favore, qualcuno si preoccupa di spiegare perché? E come forzare '\ n' per essere interpretato come un carattere speciale?Interpretazione ' n' in printf ("% s", stringa)

[email protected]:~/tmp/user/foo/bar$ ./interpretastring.x "2nd\nstr" 
1st 
str 
2nd\nstr 
[email protected]:~/tmp/user/foo/bar$ cat interpretastring.c 
#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    char *s="1st\nstr"; 

    printf("%s\n", s); 
    printf("%s\n", argv[1]); 

    return 0; 
} 

In conclusione, l'intenzione è che la seconda stringa venga stampata su due righe, proprio come la prima. Questo programma è una semplificazione. Il vero programma ha problemi a leggere da un file usando fgets (non un argomento S.O. a argv come qui), ma penso che risolvere qui risolverà anche lì.

+4

Le escape backslash sono significative nel codice sorgente C * *, ma non sono significative per 'printf' né' fgets' né per altre funzioni di libreria di runtime C. Gli argomenti della riga di comando potrebbero ottenere i loro backslash convertiti in qualcos'altro * dalla shell *, ma non si può contare su ciò che sta accadendo, né si può contare sul fatto che sia coerente con ciò che il compilatore C fa per stringere i letterali. Se vuoi tradurre '\ n' in un carattere di nuova riga nell'input del tuo programma, dovrai farlo tu stesso, a mano. – zwol

+0

Grazie. Commento molto pertinente. Forse esiste già una tale funzione nella vasta libreria C? –

+1

Mi dispiace dire che non esiste una tale funzione. – zwol

risposta

0

Per tutti gli scopi, questo si occupa solo di \n e nessun altro personaggio riceve un trattamento speciale.

Questa risposta qui fa il lavoro con minore complessità. Non cambia "2 caratteri" in "un singolo speciale \n". Cambia solo <\><n> in "<space><newline>". Va bene. Sarebbe meglio se ci fosse un C Standard Library per interpretare lo speciale chars in una stringa (come so che ha per RegExp per esempio).

/* change '\\n' into ' \n' */ 
void changebarn(char *nt) 
{ 
    while(nt!=NULL) 
     if((nt=strchr(nt,'\\'))) 
      if(*++nt=='n') 
      { 
       *nt='\n'; 
       *(nt-1)=' '; 
      } 
} 
+1

Ovviamente, ora devi preoccuparti di voler passare '\' seguito da 'n' come valori letterali, non come newline. Il che significa che è necessario consentire al backslash di uscire da sé stesso, quindi è possibile passare '" foo \\ nbar "' e ottenere 'foo \ nbar' come output letterale, con backslash e' n', non una nuova riga. – ShadowRanger

+0

Ciao @ShadowRanger, ci ho pensato prima di scrivere questo codice. Il tuo commento è molto importante per coloro che stanno leggendo questa risposta. Per quanto mi riguarda, il mio input non ha un letterale '" \\ n "'. L'unico carattere speciale che devo interpretare è solo '\ n'', e un '" \\ n "' sarà letto come '<\>< ><\n>', nessun problema. Grazie per questo, comunque. +1. –

1

Sembra che la shell non riconosca e converta la "sequenza di escape". Utilizzare un software di shell che supporti la sequenza di escape \n.

+0

Questa soluzione non risolve il mio problema. Non voglio che le terze parti interpretino il \ n '. A proposito, ho anche commentato la domanda sulla lettura di una stringa da un file usando 'fgets()'. –

+0

Quindi vuoi un codice che interpreti i due caratteri letterali '\' e 'n' in un singolo carattere di nuova riga, ma in particolare non vuoi che il codice di terze parti lo faccia? – brycem

+0

Non puoi chiedermi di cambiare la mia API per risolvere il problema. La stringa che ottengo è quella, e basta. Devo occuparmene nel mio codice (o nella libreria C). Ad ogni modo, è un problema semplice. La mia domanda riguarda più se c'è una libreria C che interpreta la stringa. –