Forum: Compiler & IDEs Wie muss ich Zeilenumbruch angeben


von SchokoladenStrom (Gast)


Lesenswert?

Hallo Leute

Ich will in einem Buffer kontrollieren ob der Zeilenumbruch angekommen 
ist. Mein Beispiel unten funktioniert nicht. Wie muss ich es richtig 
eingeben? Habe schon viel versucht. Normale Zeichenfolge funktioniert 
problemlos


if (strncmp(UARTBuffer, '#13#10', 2 ) > 0 ){}


Gruss

SchokoladenStrom

von Karl H. (kbuchegg)


Lesenswert?

C Buch! Irgendwo in Kapitel 1 oder Kapitel 2 (von 30 Kapiteln)

Das C-Zeichen für  Line Feed ist '\n' und das für Carriage Return ist 
'\r' (oder umgekehrt, kann ich mir nie merken)

if (strncmp(UARTBuffer, "\r\n", 2 ) > 0 ){}

von Bernhard R. (barnyhh)


Lesenswert?

"\n" ist Zeilenumbruch, wie jedes C-Lehrbuch schreibt.

Das sähe dann so aus:
   if (strncmp(UARTBuffer, "\n", strlen("\n") ) > 0 ){}

Bernhard

von Klaus W. (mfgkw)


Lesenswert?

1
If( strstr( UARTBuffer, "\r\n" ) ) ...
(falls es überhaupt Sinn macht, beide Zeichen zu übertragen und darauf 
zu kontrollieren, aber danach wurde nicht gefragt)

C-Grundlagen stehen in einigen Büchern...

von Klaus W. (mfgkw)


Lesenswert?

Bernhard R. schrieb:
> "\n" ist Zeilenumbruch, wie jedes C-Lehrbuch schreibt.
>
> Das sähe dann so aus:
>    if (strncmp(UARTBuffer, "\n", strlen("\n") ) > 0 ){}
>
> Bernhard

Ist das mit strlen("\n") ernst gemeint?

von SchokoladenStrom (Gast)


Lesenswert?

OK danke für eure Hilfe.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Das C-Zeichen für  Line Feed ist '\n' und das für Carriage Return ist
> '\r' (oder umgekehrt, kann ich mir nie merken)

Eselsbrücke:

'\r' : _R_eturn (Wagenrücklauf)
'\n' : _N_ew line (Neue Zeile)

Das kommt tatsächlich noch von den Teletypes der 60er/70er.

Gruß,

Frank

von Sven P. (Gast)


Lesenswert?

Vorsicht, nicht jedes System braucht Wagenrücklauf und/oder 
Zeilenvorschub...

von Hc Z. (mizch)


Lesenswert?

'\n' und '\r' sind keine Eigenschaften einer Teletype, sondern der 
Sprache C.  Sie werden spätestens vom Gerätetreiber des Betriebssystems 
in die entsprechenden Ausgabecodes umgesetzt.

Das '\n' wird z.B. für eine Teletype umgesetzt in <CR><LF> 
(Wagenrücklauf, gefolgt von Zeilenvorschub (dazu ggfs. Füllnullen)). 
Eine direkte Entsprechung zu '\n' gab es als Teletype-Zeichencode nicht. 
Die Newline-Funktionen wird dort in 2 Zeichen aufgeteilt (schon weil der 
Wagenrücklauf länger als 1 Zeichen dauerte).  Deshalb geht das '\n' auch 
nicht auf die Teletype zurück.

von Bernhard R. (barnyhh)


Lesenswert?

Klaus Wachtler schrieb:
> Bernhard R. schrieb:
>> "\n" ist Zeilenumbruch, wie jedes C-Lehrbuch schreibt.
>>
>> Das sähe dann so aus:
>>    if (strncmp(UARTBuffer, "\n", strlen("\n") ) > 0 ){}
>>
>> Bernhard
>
> Ist das mit strlen("\n") ernst gemeint?

Es gab bei mir einen Interessenkonflikt zwischen Mittagessen und 
Korrektur lesen, den das Mittagessen gewann (Brecht:"Erst kommt das 
Fressen und dann die Moral".)

Andernfalls wäre mir wohl aufgefallen, daß der Codeschnipsel des TO 
wegen falschen Parameter-Typs des 2. Aufruf-Parameters eine 
Compiler-Warnung gebracht haben muß. Dann wäre ich vielleicht darauf 
gekommen, daß die Anfrage nur mit vollständigem Code sinnvoll 
beantwortbar ist.

Ich verspreche, daß ich derartige Konflikte in Zukunft sauber auflösen 
werde.

Bernhard

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Hc Zimmerer schrieb:
> Das '\n' wird z.B. für eine Teletype umgesetzt in <CR><LF>
> (Wagenrücklauf, gefolgt von Zeilenvorschub (dazu ggfs. Füllnullen)).

Nur, wenn das TTY im sog. cooked-Mode ist, im raw-Mode ist das nicht der 
Fall. Da musst Du dann selbst beide Zeichen senden.

man stty
man termios

> Eine direkte Entsprechung zu '\n' gab es als Teletype-Zeichencode nicht.

Natürlich: die Walzendrehung.

Hier als interessante Lektüre:

http://en.wikipedia.org/wiki/ASR-33_Teletype

Ich habe zu meiner Studienzeit selbst als Operator/Programmierer an 
einer Teletype an einer PDP11/70 gesessen. Die Console konnte einen 
Wagenrücklauf ohne Papiervorschub. Und auch einen Papiervorschub ohne 
Wagenrücklauf. Wenn man das tty in den Raw-Modus gestellt hat und hat 
dann per cat eine Datei ausgegeben, dann kam die in folgender Form:

Erste Zeile
           Zweite Zeile
                       Dritte Zeile

weil dann tatsächlich nur die Walzendrehung ('\n' == Newline) 
durchgeführt wurde und nicht der Wagenrücklauf.

Oder umgekehrt nur CR, zum Beispiel bei Unterstreichen/Durchstreichen: 
Wagenrücklauf und dann Underscores bzw. Minuszeichen.

Wohlgemerkt: Das hat nur im raw-Mode funktioniert. Tatsächlich wird vom 
Gerätetreiber bei unixoiden Systemen im Cooked-Mode das "\n" nach "\r\n" 
transferiert. Bei VAX/VMS hat es die C-Runtime-Bibliothek gemacht - 
nicht der Gerätetreiber, da VMS-Terminals immer im Raw-Mode angesteuert 
werden.

Hier noch ein paar Zeilen aus 
http://www.aspmessageboard.com/showthread.php?t=109291 zur ASR-33 
Teletype:

---------------------------- schnipp -----------------------------
It gave you a keyboard and a printer, all in one. And it was able to 
print at an amazing 10 characters per second! (110 baud, to be more 
precise. Yes, 110 baud...vs. todays modems at 56,000 baud...and faster 
with DSL et al., of course.)

Anyway, the ASR-33 had both a RETURN key and a LINEFEED key, and you 
could use one without the other!

For example, to underline words in a line, you would hit the RETURN key 
(or send the "keycode" for it from the computer to the teletype) and 
then hit enough spaces to put you in the right place, and then type the 
underline character.

When you really wanted to go to the next line, you pushed BOTH the 
RETURN key and the LINE FEED key.

Well, guess what the keycode for the RETURN key was? Yep, CHR(13) or 
CHR(&H000D) or, what else, vbCR. [Carriage Return...*literally* the 
carriage that did the printing was "return"ed to the left side of the 
paper. The paper didn't move, but the carriage with the print head did.]

And guess what the keycode for the linefeed key was? Yep, CHR(10) or 
CHR(&H000A) or, ta da!, vbLF [Line Feed...this code didn't affect the 
carriage at all; instead it just advanced the paper by one line].
---------------------------- schnapp -----------------------------

Es gab also '\n' == 0x0A und '\r' == 0x0D auch auf der Teletype. Das 
kannte ich damals (Anfang der 80er) sowohl für sämtliche UNIX-Varianten, 
als auch für VAX/VMS und auch für RT-11 auf einer PDP.

Gruß,

Frank

von Klaus W. (mfgkw)


Lesenswert?

Bernhard R. schrieb:
> Klaus Wachtler schrieb:
>> Bernhard R. schrieb:
>>> "\n" ist Zeilenumbruch, wie jedes C-Lehrbuch schreibt.
>>>
>>> Das sähe dann so aus:
>>>    if (strncmp(UARTBuffer, "\n", strlen("\n") ) > 0 ){}
>>>
>>> Bernhard
>>
>> Ist das mit strlen("\n") ernst gemeint?
>
> Es gab bei mir einen Interessenkonflikt zwischen Mittagessen und
> Korrektur lesen, den das Mittagessen gewann (Brecht:"Erst kommt das
> Fressen und dann die Moral".)
>
> Andernfalls wäre mir wohl aufgefallen, daß der Codeschnipsel des TO
> wegen falschen Parameter-Typs des 2. Aufruf-Parameters eine
> Compiler-Warnung gebracht haben muß. Dann wäre ich vielleicht darauf
> gekommen, daß die Anfrage nur mit vollständigem Code sinnvoll
> beantwortbar ist.
>
> Ich verspreche, daß ich derartige Konflikte in Zukunft sauber auflösen
> werde.
>
> Bernhard

Ich hatte eher mit etwas anderem Probleme:
So wie du es schrubst, testest du nur auf einen kompletten String,
der aus dem Zeilenende besteht, und nicht auf einen String, der
lediglich mit dem Zeilentrenner endet.

Sorry, mein Gemecker war zu knapp - das war ein Interessenskonflikt
mit dem Hund, der rauswollte.

von Andreas F. (aferber)


Lesenswert?

Sven P. schrieb:
> Vorsicht, nicht jedes System braucht Wagenrücklauf und/oder
> Zeilenvorschub...

Um den Punkt nochmal aufzugreifen: bei textbasierten Netzwerkprotokollen 
z.B. (SMTP, HTTP etc.) ist es allgemein üblich, Zeilenenden durch "\r\n" 
zu signalisieren. Beim Senden sollte man das dann auch genau so 
einhalten, beim Empfangen wird jedoch oft nur auf das '\n' geachtet, 
und das '\r' direkt davor wird ignoriert ([1]), so es denn vorhanden 
ist. Dieses Verhalten erhöht die Wahrscheinlichkeit, auch mit "kaputten" 
Gegenstellen erfolgreich zu kommunizieren (Robustness Principle).

Bei einem eigenen Protokoll hat man natürlich grundsätzlich die freie 
Wahl, wobei es manchmal empfehlenswert ist, sich auch an 
"Gewohnheitsstandards" zu halten (Principle of Least Surprise).

Andreas

[1] Wenn zeichenweise übertragen wird (UART z.B.) und man das '\r' nicht 
für andere Zwecke (Binärdaten) im Datenstrom braucht, kann man das 
natürlich einfach gleich verwerfen, ohne es überhaupt in den 
Empfangspuffer zu schreiben.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Andreas Ferber schrieb:
> [...] Beim Senden sollte man das dann auch genau so
> einhalten, beim Empfangen wird jedoch oft nur auf das '\n' geachtet,
> und das '\r' direkt davor wird ignoriert ([1]), so es denn vorhanden
> ist. Dieses Verhalten erhöht die Wahrscheinlichkeit, auch mit "kaputten"
> Gegenstellen erfolgreich zu kommunizieren (Robustness Principle).

Genauso mache ich es auch: Beim Senden \r\n schicken, beim Empfangen \r 
ignorieren und lediglich auf das \n als Zeilenende reagieren. So kann 
man in der Regel eigentlich nichts falsch machen.

Gruß,

Frank

P.S.
Das Verfahren, die Carriage-Returns zu ignorieren, nutze ich nicht nur 
auf einem µC in Verbindng mit dem UART, sondern wende das unter Linux 
auch an auf ASCII-Dateien, die ich lese/parse. Der Vorteil ist, dass man 
da auch mit Dateien, die unter Windows/DOS (\r\n) erzeugt wurden, 
klarkommt.

Witzigerweise scheint das auch WordPad unter Windows so zu machen, denn 
es kommt mit unixoiden ASCII-Dateien (nur \n am Zeilenende) problemlos 
klar. Notepad kann das nicht. Selbst da ist MS inkonsequent. ;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.