Wenn ich folgenden Code verwende:
#include <stdio.h>
int main(void)
{
printf("%s","Hello world\nHello world");
return 0;
}
es druckt als:
Hello world
Hello world
Wie kann ich das verhindern und als unformatiertes String-Literal in C ausgeben? Ich meine, es sollte angezeigt werden, wie es im Terminalfenster wie folgt ist:
Hello world\nHello world
Ich weiß, dass ich dies mit Backslash für printf erreichen kann, aber gibt es eine andere C-Funktion oder einen anderen Weg, dies ohne Backslash zu tun? Es wäre hilfreich beim Lesen von Dateien.
Dafür gibt es keinen eingebauten Mechanismus. Sie müssen es manuell tun, Zeichen für Zeichen. Die Funktionen in ctype.h
können jedoch hilfreich sein. Insbesondere in der Ländereinstellung "C" ist die Funktion isprint
für alle Grafikzeichen im Basisausführungszeichensatz garantiert wahr, was praktisch mit allen Grafikzeichen in 7-Bit identisch ist ASCII plus Leerzeichen; und es ist garantiert, dass nicht für alle control -Zeichen in 7-Bit-ASCII zutreffend ist, einschließlich Tabulatorzeichen, Wagenrücklauf usw.
Hier ist eine Skizze:
#include <stdio.h>
#include <ctype.h>
#include <locale.h>
int main(void)
{
int x;
setlocale(LC_ALL, "C"); // (1)
while ((x = getchar()) != EOF)
{
unsigned int c = (unsigned int)(unsigned char)x; // (2)
if (isprint(c) && c != '\\')
putchar(c);
else
printf("\\x%02x", c);
}
return 0;
}
Dies entgeht weder '
noch "
, sondern \
und es ist unkompliziert, dies zu erweitern, wenn Sie es brauchen.
Das Drucken von \n
für U + 000A, \r
für U + 000D usw. bleibt als Übung bestehen. Der Umgang mit Zeichen außerhalb des grundlegenden Ausführungszeichensatzes (z. B. UTF-8-Kodierung von U + 0080 bis U + 10FFFF) wird ebenfalls als Übung gelassen.
Dieses Programm enthält zwei Dinge, die für eine vollständig standardkonforme C-Bibliothek nicht erforderlich sind, aber nach meiner Erfahrung auf realen Betriebssystemen erforderlich waren. Sie sind mit (1)
und (2)
gekennzeichnet.
1) Hiermit wird die "locale" -Konfiguration explizit so festgelegt, wie sie ist vermutlich .
2) Der von getchar
zurückgegebene Wert ist eine int
. Es ist angenommen entweder eine Zahl in dem durch unsigned char
darstellbaren Bereich (normalerweise 0-255 einschließlich) oder der spezielle Wert EOF
(der nicht in dem durch unsigned char
darstellbaren Bereich ist) . Es ist jedoch bekannt, dass fehlerhafte C-Bibliotheken negative Zahlen für Zeichen mit dem höchsten gesetzten Bit zurückgeben. In diesem Fall druckt die printf
(zum Beispiel) \xffffffa1
, wenn \xa1
gedruckt werden soll. Das Umwandeln von x
in unsigned char
und dann wieder von unsigned int
korrigiert dies.
So etwas könnte das sein, was Sie wollen. Führen Sie myprint(c)
aus, um das Zeichen C oder eine druckbare Darstellung davon zu drucken:
#include <ctype.h>
void myprint(int c)
{
if (isprint(c))
putchar(c); // just print printable characters
else if (c == '\n')
printf("\\n"); // display newline as \n
else
printf("%02x", c); // print everything else as a number
}
Wenn Sie Windows verwenden, denke ich, dass alle Ihre Zeilenumbrüche CRLF (Wagenrücklauf, Zeilenvorschub) sind, so dass sie als 0d\n
so gedruckt werden, wie ich diese Funktion geschrieben habe.
Wenn ich die Frage verstehe, wenn Sie eine Zeichenfolge mit Steuerzeichen wie Zeilenumbruch, Tabulator, Rücktaste usw. haben, möchten Sie eine Textdarstellung dieser Zeichen drucken, anstatt sie als Steuerzeichen zu interpretieren.
Leider gibt es keinen integrierten printf
-Konvertierungsspezifizierer, der dies für Sie tun wird. Sie müssen die Zeichenfolge Zeichen für Zeichen durchgehen, jeden testen, um zu sehen, ob es sich um ein Steuerzeichen handelt, und einen entsprechenden Text schreiben.
Hier ist ein schnelles, leicht getestetes Beispiel:
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
...
char *src="This\nis\ta\btest";
char *lut[CHAR_MAX] = {0}; // look up table for printable equivalents
// of non-printable characters
lut['\n'] = "\\n";
lut['\t'] = "\\t";
lut['\b'] = "\\b";
...
for ( char *p = src; *p != 0; p++ )
{
if ( isprint( *p ) )
putchar( *p );
else
fputs( lut[ (int) *p], stdout ); // puts adds a newline at the end,
// fputs does not.
}
putchar( '\n' );
Vielen Dank an den Benutzer@chunkfür die Verbesserung dieser Antwort.
Warum haben Sie keine Allzwecklösung geschrieben? Es würde Sie in Zukunft von vielen Problemen abhalten.
char *
str_escape(char str[])
{
char chr[3];
char *buffer = malloc(sizeof(char));
unsigned int len = 1, blk_size;
while (*str != '\0') {
blk_size = 2;
switch (*str) {
case '\n':
strcpy(chr, "\\n");
break;
case '\t':
strcpy(chr, "\\t");
break;
case '\v':
strcpy(chr, "\\v");
break;
case '\f':
strcpy(chr, "\\f");
break;
case '\a':
strcpy(chr, "\\a");
break;
case '\b':
strcpy(chr, "\\b");
break;
case '\r':
strcpy(chr, "\\r");
break;
default:
sprintf(chr, "%c", *str);
blk_size = 1;
break;
}
len += blk_size;
buffer = realloc(buffer, len * sizeof(char));
strcat(buffer, chr);
++str;
}
return buffer;
}
int
main(const int argc, const char *argv[])
{
puts(str_escape("\tAnbms\n"));
puts(str_escape("\tA\v\fZ\a"));
puts(str_escape("txt \t\n\r\f\a\v 1 \t\n\r\f\a\v tt"));
puts(str_escape("dhsjdsdjhs hjd hjds "));
puts(str_escape(""));
puts(str_escape("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\'()*+,-./:;<=>[email protected][\\]^_`{|}~ \t\n\r\f\a\v"));
puts(str_escape("\x0b\x0c\t\n\r\f\a\v"));
puts(str_escape("\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14"));
}
\tAnbms\n
\tA\v\fZ\a
txt \t\n\r\f\a\v 1 \t\n\r\f\a\v tt
dhsjdsdjhs hjd hjds
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>[email protected][\]^_`{|}~ \t\n\r\f\a\v
\v\f\t\n\r\f\a\v
\a\b\t\n\v\f\r
Diese Lösung basiert auf Informationen aus der Wikipedia https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences Und den Antworten anderer Benutzer von stackoverflow.com.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.6 (jessie)
Release: 8.6
Codename: jessie
$ uname -a
Linux localhost 3.16.0-4-AMD64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.