2013-07-23 9 views
17

Dokumentacja printf() mówi, że jeśli ktoś chce wydrukować % w C, może on użyć:Dlaczego procentowy znak nie jest uniknięty z ukośnikiem odwrotnym w C?

printf("%%") 

Dlaczego nie:

printf("\%") 

jak w przypadku innych znaków specjalnych?

+1

Sprawdź ten link, aby uzyskać więcej informacji; http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.cmds/doc/aixcmds4/printf.htm – JNL

+1

To jest właśnie droga do printf. Wolałbym używać tego odsyłacza http://www.cplusplus.com/reference/cstdio/printf/ – GreenScape

Odpowiedz

28

Ponieważ % jest obsługiwane przez printf. Nie jest to znak specjalny w C, ale samo to traktuje inaczej.

35

Ukośnik odwrotny jest przetwarzany przez kompilator podczas interpretacji tekstu źródłowego programu. Tak więc powszechnym wynikiem jest to, że tekst źródłowy "\%" tworzy ciąg zawierający "%".

Łańcuch formatu jest interpretowany przez procedurę printf, więc przetwarza przekazywane do niej znaki. W tym czasie odwrócony ukośnik nie jest już obecny, więc nigdy go nie widzi.

Technicznie, \% nie jest legalne w dosłownym ciągu literowym. Postać \ rozpoczyna sekwencję ucieczki, a jedynie sekwencje prawne są wymienione w katalogu C 2011 6.4.4.4 1. Są \ następnie ', ", ?, \, a, b, f, n, r, t, v , od jednej do trzech cyfr ósemkowych, x i cyfr szesnastkowych, u i czterech cyfr szesnastkowych lub U i ośmiu cyfr szesnastkowych.

Jeśli printf został zaprojektowany tak, aby backsleshem by uciec procent, wtedy trzeba by przekazać go ukośnika uciekając się ukośnik w tekście źródłowym, więc trzeba by napisać:

printf("\\%"); 
+1

+1 dla ostrożnego sformułowania "cyfr xi szesnastkowych" http: // stackoverflow.com/questions/5784969/when-did-c-compilers-start-considering-więcej niż dwóch-hex-cyfr-in-string-lite – chux

3

Konwencja jest taka, że ​​specjalne postacie uciekają. Zamiast więc używać ukośnika odwrotnego, aby uniknąć procentu, ucieka on sam. (Zauważ, że aby przekazać ukośnik odwrotny do printf, musisz napisać literał łańcuchowy jako "\\%".)

+0

Konwencja użyta z '\' przez kompilator i '%' przez printf jest to, że te postacie uciekają. Konwencja w literałach łańcuchowych i znakach jest taka, że ​​odwrotny ukośnik służy do unikania ograniczników końcowych. Osobiście jestem przekonany, że najlepiej jest, gdy uciekła reprezentacja postaci ucieczki jest tą postacią, po której następuje konkretna * coś innego *; i unikaj ucieczki, które wyglądają jak inne rzeczy, ale pomysł podwojenia znaków ucieczki i poprzednich rzeczy, takich jak cytaty z ucieczkami (zamiast używania np. '\ q' jako cytatu z ewakuacją) wydaje się dość powszechny. – supercat

+0

Również w łańcuchach znaków i literach znaków, ukośnik odwrotny jest metaznakiem i sam się wymyka; znaki cudzysłowu nie uciekają w większości języków, zamiast tego używa się odwrotnego ukośnika. Myślę, że zgadzasz się ze mną? Istnieją dziwne schematy, w których podwójnie cytowane znaki są używane do reprezentowania dosłownego cudzysłowu (UTR35 jest tego przykładem i jest prawdziwym koszmarem). –

+0

Podwajanie metaznaków do reprezentowania siebie jest powszechnym wzorcem, chociaż nie znam żadnej realnej korzyści poza popularnością, ponieważ oznacza to, że nie można wiedzieć, co oznacza konkretna postać, nie będąc w stanie zobaczyć dowolnej liczby znaków przed to. Posiadanie reprezentacji escaped dla '\' be '\!' Uniknie dwuznaczności co do tego, że łańcuch kończący się na '\\\\\\\\" oznacza, że ​​[jest zacytowaną częścią łańcucha znaków, czy nie? ] Inne języki stosują różne podejścia, ale czasami generują niejasności własne (np. Ciągi w formacie .NET). – supercat

0

Możesz to zrobić !!!!!

#include <iostream> 
#include <string> 
#include "stdio.h" 
using namespace std; 



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


    printf("hhhhhhh %s \n","\%"); 
    printf("hhhhhhh \n"); 

    return 0; 
} 

problem istnieje printf i różnią się od kompilator wykorzystać .. Z wxWidget Ilb nie można używać printf dwie sekwencje

printf(" xxxxxx \0x81 xx \0x82 xx \n"); 

don t go. Ale jeśli używasz

printf(" xxxxxx %s xx %s \n","\0x81","\0x82"); 

masz rację. A plus

Powiązane problemy