Printf einen Puffer von char mit Länge in C

Lesezeit: 4 Minuten

Benutzer-Avatar
Roman Rdgz

Ich habe einen Puffer, den ich über eine serielle Schnittstelle erhalte. Wenn ich ein bestimmtes Zeichen erhalte, weiß ich, dass eine ganze Zeile angekommen ist, und ich möchte es damit drucken printf Methode. Aber jede Zeile hat einen anderen Längenwert, und wenn ich einfach gehe mit:

printf("%s", buffer);

Ich drucke die Zeile plus zusätzliche Zeichen, die zur vorherigen Zeile gehören (falls sie länger als die aktuelle war).

ich lese hier dass es möglich ist, zumindest in C++, zu sagen, wie viele Zeichen Sie lesen möchten, wenn a gegeben ist %saber es hat keine Beispiele und ich weiß nicht, wie man es in C macht. Irgendwelche Hilfe?

Ich denke, ich habe drei Lösungen:

  • Zeichen für Zeichen mit a drucken for Schleife
  • mit dem Abschlusszeichen
  • oder mit .*

FRAGE: Was ist schneller? Weil ich an einem Mikrochip-PIC arbeite und möchte, dass es so schnell wie möglich geht

  • Wenn Sie das erhalten haben “bestimmter Charakter” und habe es angehängt bufferein Nullzeichen anhängen (\0) auch. Das „erzählt“ sprintf() wann das Drucken von Zeichen beendet werden soll.

    – Linus Kleen

    17. November 2011 um 16:31 Uhr

Benutzer-Avatar
Sören

Sie können entweder ein Nullzeichen nach Ihrem Abschlusszeichen hinzufügen, und Ihr printf funktioniert, oder Sie können ein hinzufügen '.*' in Ihrer printf-Anweisung und geben Sie die Länge an

printf("%.*s",len,buf);

In C++ würden Sie wahrscheinlich stattdessen std::string und std::cout wie folgt verwenden:

std::cout << std::string(buf,len);

Wenn Sie nur die schnellste Geschwindigkeit und keine Formatierung wollen, dann verwenden Sie

fwrite(buf,1,len,stdout);

  • Perfekt. Ich habe also drei Lösungen: Zeichen für Zeichen mit einer for-Schleife drucken, das Abschlusszeichen verwenden oder .* verwenden. FRAGE IST: Welches ist schneller? Weil ich an einem Mikrochip-PIC arbeite und möchte, dass es schnell geht

    – Roman Rdgz

    17. November 2011 um 16:42 Uhr

  • @RomanRdgz: meine Vermutungen: fwrite oder Nullterminierung+fputs sollte die schnellste sein, gefolgt von null-termination+printf (könnte langsamer sein, da möglicherweise die Formatzeichenfolge analysiert werden muss, es sei denn, der Compiler ist sehr schlau). printf mit .* (muss sicherlich den Formatstring parsen) und zuletzt Zeichen für Zeichen drucken (wahrscheinlich das langsamste, wegen all der Funktionsaufrufe – das könnte jedoch inline sein).

    – Matteo Italien

    17. November 2011 um 16:47 Uhr


  • Außerdem ist Ihre C ++ – Version ziemlich ineffizient, Sie weisen Dinge auf dem Heap zu / geben sie frei (erstellen eine Instanz von std::string) bei einem einfachen Aufruf an cout.write wäre genug. Nicht, dass es auf einer normalen Maschine hin und wieder eine Rolle spielen würde, aber bei sehr begrenzten Ressourcen oder in einer engen Schleife kann es auffallen.

    – Matteo Italien

    17. November 2011 um 16:48 Uhr


  • Ich verwende den CCS-Compiler und glaube nicht, dass er cout.write hat. Deshalb verwende ich fputs oder printf. Danke für deine Info @Matteo Italia

    – Roman Rdgz

    17. November 2011 um 16:50 Uhr

  • @RomanRdgz: wenn ja cout wirst du sicher haben cout.writedas war jedenfalls nur ein Kommentar zur C++-Lösung von @Soren, für C-Lösungen habe ich bereits meine Antwort geschrieben 🙂 .

    – Matteo Italien

    17. November 2011 um 16:51 Uhr


Benutzer-Avatar
Matteo Italien

Die Zeichenfolge, die Sie haben, ist nicht nullterminiert, also printf (und jede andere C-String-Funktion) kann ihre Länge nicht bestimmen, daher schreibt sie die dort gefundenen Zeichen weiter, bis sie auf ein zufällig vorhandenes Nullzeichen stößt.

Um Ihr Problem zu lösen, können Sie entweder:

  • verwenden fwrite Über stdout:

    fwrite(buffer, buffer_length, 1, stdout);
    

    Das funktioniert, weil fwrite ist nicht dafür gedacht, nur Zeichenketten zu drucken, sondern jede Art von Daten, also sucht es nicht nach einem abschließenden Nullzeichen, sondern akzeptiert die Länge der zu schreibenden Daten als Parameter;

  • Beenden Sie Ihren Puffer vor dem Drucken manuell mit Null:

    buffer[buffer_length]=0;
    printf("%s", buffer); /* or, slightly more efficient: fputs(buffer, stdout); */
    

    Dies könnte eine bessere Idee sein, wenn Sie eine andere Zeichenfolgenverarbeitung durchführen müssen bufferdie nun nullterminiert sind und so von normalen C-String-Verarbeitungsfunktionen verwaltet werden können.

  • Ich bin überrascht, dass Antworten auf Duplikate dieser SO-Frage diese Methode nicht enthalten, sondern nur vorschlagen for Schleifen …

    – Alex

    5. Juli 2017 um 13:45 Uhr


Sobald Sie das Ende der Zeile identifiziert haben, müssen Sie a anhängen '\0' Zeichen an das Ende des Puffers, bevor es an gesendet wird printf.

  • Jeder, der abgelehnt hat, möchte erklären, warum, damit ich meine Antwort verbessern kann?

    – Michael Preis

    22. November 2011 um 16:05 Uhr

  • Sie sollten sagen, was das OP falsch gemacht hat, und wie Sie es korrigieren können.

    – Alex

    5. Juli 2017 um 13:46 Uhr

Sie können eine NUL (0x0) in den Puffer schreiben, nachdem Sie das letzte Zeichen erhalten haben.

buffer[i] = 0;

1362210cookie-checkPrintf einen Puffer von char mit Länge in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy