2009-07-03 13 views
5

Piszę program, który używa wydruków zrzut szesnastkowy jego wejścia. Jednak mam problemy z przekazaniem nowych linii, zakładek itp. I niszczę moje formatowanie wyjściowe.Jak wydrukować " n" zamiast nowej linii?

Jak mogę użyć printf (lub cout chyba) do wydrukowania '\ n' zamiast drukowania faktycznego znaku nowej linii? Czy po prostu potrzebuję do tego ręcznego parsowania?

EDYCJA: Moje dane są odbierane dynamicznie, nie chodzi tylko o \ n, którego jestem autorem, ale o wszystkie symbole. Na przykład, to jest moje oświadczenie printf:

printf("%c", theChar); 

Jak mogę dokonać tej druku \ n znak nowej linii, kiedy jest przekazywana jako theChar ale nadal sprawiają, że drukowanie normalny tekst kiedy theChar jest ważna postać wydruku?

+1

Należy pamiętać, że nie ma możliwości, aby pojedyncze wywołanie printf ("% c", foo) mogło wyprowadzić \ n, ciąg dwóch znaków. Zasadniczo musisz wybrać pomiędzy zmianą danych wejściowych (zastępując "\ n" przez "\\ n") lub dobrym starym sposobem, jeśli (theChar == '\ n'). – ojrac

Odpowiedz

36

Drukuj "\\ n" - "\\" wyświetla "\", a następnie "n" jest rozpoznawane jako zwykły symbol. Aby uzyskać więcej informacji, zobacz here.

6

można uciec odwrotny ukośnik, aby wydrukować tylko normalne backslash: "\\n".

Edit: Tak będziesz musiał zrobić kilka ręcznego parsowania. Jednak kod, który to zrobi, będzie po prostu wyszukiwaniem i zamianą.

8

Wystarczy użyć "\\ n" (dwa ukośniki)

1

Wystarczy użyć String::replace zastąpić znaki naruszające przed wywołaniem printf.

Można owinąć printf zrobić coś takiego:

void printfNeat(char* str) 
{ 
    string tidyString(str); 
    tidyString.replace("\n", "\\n"); 
    printf(tidyString); 
} 

... i po prostu dodać dodatkowe zastąpić oświadczenia pozbyć się niechcianych innych znaków.

[Edytuj] lub jeśli chcesz używać argumentów, spróbuj tego:

void printfNeat(char* str, ...) 
{ 
    va_list argList; 
    va_start(argList, msg); 

    string tidyString(str); 
    tidyString.replace("\n", "\\n"); 
    vprintf(tidyString, argList); 

    va_end(argList); 
} 
+0

W ten sposób nie działa std :: basic_string :: replace. Z http://en.cppreference.com/w/cpp/string/basic_string/replace widzimy, że zamień 'zastąpi część ciągu oznaczoną przez [pos, pos + count] lub [first, last]' with nowy ciąg. Nie wyszukuje oryginalnego ciągu znaków i zastępuje znalezione wystąpienia. – Jon

22

Funkcja printchar() poniżej wypisze kilka znaków jak „specjalne”, a następnie wydrukować kod ósemkowy dla znaków z zakresu (a la Emacs), ale drukuj normalne znaki w przeciwnym razie. Pozwoliłem również, aby po '\n' wydrukować prawdziwy '\n', aby twoje wyjście było bardziej czytelne. Zauważ też, że używam int w pętli w main po prostu aby móc iterować w całym zakresie unsigned char. Podczas korzystania prawdopodobnie uzyskasz numer unsigned char, który czytasz z zestawu danych.

#include <stdio.h> 

static void printchar(unsigned char theChar) { 

    switch (theChar) { 

     case '\n': 
      printf("\\n\n"); 
      break; 
     case '\r': 
      printf("\\r"); 
      break; 
     case '\t': 
      printf("\\t"); 
      break; 
     default: 
      if ((theChar < 0x20) || (theChar > 0x7f)) { 
       printf("\\%03o", (unsigned char)theChar); 
      } else { 
       printf("%c", theChar); 
      } 
     break; 
    } 
} 

int main(int argc, char** argv) { 

    int theChar; 

    (void)argc; 
    (void)argv; 

    for (theChar = 0x00; theChar <= 0xff; theChar++) { 
     printchar((unsigned char)theChar); 
    } 
    printf("\n"); 
} 
+2

+1: Dobry pomysł na < 20 and > 127 catch –

+3

Powinien być <32 (lub 0x20) i> = 127. Również dla% o musisz rzucićChar na unsigned char (lub & 0xff), ponieważ char jest zwykle podpisany. – mark4o

+0

Dzięki @ mark4o, masz rację co do 0x20 i 32. Naprawiono moją odpowiedź. –

5

Jeśli chcesz się upewnić, że nie drukuje żadnych znaków zakaz druku, można korzystać z funkcji w ctype.h jak isprint:

if(isprint(theChar)) 
    printf("%c", theChar) 
else 
    switch(theChar) 
    { 
    case '\n': 
    printf("\\n"); 
    break; 
    ... repeat for other interesting control characters ... 
    default: 
    printf("\\0%hho", theChar); // print octal representation of character. 
    break; 
    } 
3

Oprócz przykładów podanych przez inne osoby, powinieneś spojrzeć na funkcje klasyfikacji postaci, takie jak isprint() i iscntrl(). Za ich pomocą można wykryć, które znaki są lub nie można drukować bez konieczności szyfrowania wartości szesnastkowych z tabeli ascii.

3

W języku C/C++ znak "\" jest zarezerwowany jako znak escape. Więc kiedy chcesz wydrukować "\", musisz wpisać "\". Tak aby drukować rzeczywiste „\ n” wartość chcesz wydrukować następujący:

printf("\\n"); 
-2

Istnieją trzy rozwiązania dla tego pytania:

Rozwiązanie 1: Każdy Symbol, ilość, alfabet ma własną wartość ASCII . Wartość ASCII "\" jako 92 i "n" jako 110. Bezpośrednie wartości (Liczby (ASCII)) są przechowywane na dwóch zmiennych liczb całkowitych. Podczas drukowania używany jest specyfikator formatu% c (znak).

void main() { 
    int i=92, j=110; 
    clrscr(); 
    printf("%c%c", i, j); 
    getch(); 
} 

Wypróbuj go w swoim oprogramowaniu C ...

Rozwiązanie 2:

Programy działa. Ale myślę, że to nie jest fair ... Na ekranie wyjściowego wpisz wejście jako \ n ... dostaniesz kolejną \ n ..

void main() { 
    char a[10]; 
    gets(a); 
    printf("\n\n\n\n"); 
    puts(a); 
    getch(); 
} 

wypróbować programy

Rozwiązanie 3: już wspomniano wyżej użycie \ n

0

Począwszy od C++ 11 można również wykorzystywać surowe ciągi

std::printf(R"(\\n)"); 

wszystko wewnątrz R"( i )" zostaną wydrukowane dosłownie. sekwencje specjalne nie będą przetwarzane.

Powiązane problemy