2016-04-14 14 views
5

Ten fragment kodu działa nieco dziwnie według mojego gustu. Proszę, czy ktoś chce wyjaśnić, dlaczego? I jak zmusić '\ n' do interpretowania jako specjalnego znaku?Interpretowanie " n" w printf ("% s", ciąg)

[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; 
} 

Dolna linia, intencją jest, aby drugi ciąg był drukowany w dwóch liniach, podobnie jak pierwszy. Ten program jest uproszczeniem. Prawdziwy program ma problemy z odczytaniem pliku za pomocą fgets (nie jest to argument S.O. do argv, jak tutaj), ale myślę, że rozwiązanie tutaj również rozwiąże ten problem.

+4

Ucieczki odwrotne są znaczące w kodzie źródłowym C *, ale nie są znaczące dla 'printf' ani' fgets' ani żadnej innej funkcji biblioteki wykonawczej C. Argumenty linii poleceń mogą przekonwertować ich ukośnik odwrotny na coś innego * przez powłokę *, ale nie możesz na to liczyć, ani nie możesz liczyć na to, że jest on zgodny z tym, co robi kompilator C, aby napisać ciągi literałów. Jeśli chcesz przetłumaczyć '\ n' na znak nowego wiersza w swoim wejściu do programu, musisz to zrobić samodzielnie, ręcznie. – zwol

+0

Dziękuję. Bardzo trafny komentarz. Może taka funkcja jest już dostępna w rozległej bibliotece C? –

+1

Z przykrością muszę stwierdzić, że nie ma takiej funkcji. – zwol

Odpowiedz

0

Dla wszystkich celów, to po prostu dbać o \n i żadne inne postacie nie są traktowane w specjalny sposób.

Ta odpowiedź wykonuje zadanie z mniejszą złożonością. Nie zmienia "2 znaki" w "jeden pojedynczy specjalny \n". Po prostu zmienia się <\><n> na "<space><newline>". W porządku. Byłoby lepiej, gdyby było C Standard Library interpretować specjalne chars w ciągu znaków (jak wiem, że na przykład dla RegExp).

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

Oczywiście, teraz musisz się martwić, że chcesz przekazać '\', a następnie 'n' jako literały, a nie znaki nowej linii. Co oznacza, że ​​musisz zezwalać ukośnemu ukośnikowi na ucieczkę, więc możesz przekazać '' foo \\ nbar "' i uzyskać 'foo \ nbar' jako literalne wyjście, z ukośnikiem odwrotnym i' n', a nie znakiem nowej linii. – ShadowRanger

+0

Hi @ShadowRanger, pomyślałem o tym przed napisaniem tego kodu. Twój komentarz jest bardzo ważny dla tych, którzy czytają tę odpowiedź. Jeśli chodzi o mnie, moje dane wejściowe nie zawierają literału "" \\ n "'. Jedynym specjalnym znakiem, który muszę zinterpretować, jest po prostu '\ n'', a' '\\ n" 'zostanie odczytane jako' 'bez problemu. Dzięki za wskazanie tego. +1. –

1

Wygląda na to, że powłoka nie rozpoznaje i nie przekształca "sekwencji ucieczki". Użyj oprogramowania powłoki, które obsługuje sekwencję specjalną \n.

+0

To rozwiązanie nie rozwiązuje mojego problemu. Nie chcę, aby trzecie części interpretowały "\ n". BTW, ja również skomentowałem w pytaniu o czytanie napisu z pliku za pomocą 'fgets()'. –

+0

A więc chcesz kodu, który interpretuje literalne 2 znaki "\" i "n" w pojedynczym znaku nowej linii, ale czy nie chcesz tego robić? – brycem

+0

Nie możesz poprosić mnie o zmianę interfejsu API w celu rozwiązania problemu. Ciąg, który otrzymuję, jest taki, i to jest to. Muszę sobie z tym poradzić w moim własnym kodzie (lub bibliotece C). W każdym razie jest to prosty problem. Moje pytanie dotyczy raczej biblioteki C, która interpretuje ciąg znaków. –