Wie richte ich eine solche Zahl in C aus?

Lesezeit: 11 Minuten

Benutzeravatar von rfgamaral
rfgamaral

Ich muss eine Reihe von Zahlen in C mit ausrichten printf() wie dieses Beispiel:

-------1
-------5
------50
-----100
----1000

Natürlich gibt es zwischen all diesen Zahlen Zahlen, aber das ist für das vorliegende Problem nicht relevant … Oh, betrachten Sie die Bindestriche als Leerzeichen, ich habe Bindestriche verwendet, damit es einfacher ist zu verstehen, was ich will.

Ich kann nur das:

----1---
----5---
----50--
----100-
----1000

Oder dieses:

---1
---5
--50
-100
1000

Aber nichts davon ist das, was ich will, und ich kann nicht erreichen, was im ersten Beispiel angezeigt wird, indem ich nur printf() verwende. Ist es überhaupt möglich?

BEARBEITEN:

Entschuldigung Leute, ich war in Eile und habe mich nicht gut erklärt … Mein letztes Beispiel und alle Ihre Vorschläge (etwas wie “%8d” zu verwenden) funktionieren nicht, weil, obwohl die letzte Zahl 1000 ist, es nicht funktioniert unbedingt bis 1000 oder sogar 100 oder 10 gehen.

Unabhängig von der Anzahl der anzuzeigenden Ziffern möchte ich höchstens 4 führende Leerzeichen für die größte Zahl. Nehmen wir an, ich muss Ziffern von 1 bis 1000 (A) und 1 bis 100 (B) anzeigen und verwende für beide “%4d”, dies wäre die Ausgabe:

EIN:

---1
....
1000

Welche Ausgabe möchte ich…

B:

---1
....
-100

Das ist nicht die Ausgabe, die ich will, ich will eigentlich dies:

--1
...
100

Aber wie gesagt, ich weiß nicht genau, wie viele Zahlen ich drucken muss, es kann 1 Ziffer haben, es kann 2, 3 oder mehr haben, die Funktion sollte für alle vorbereitet sein. Und ich möchte vier zusätzliche zusätzliche führende Leerzeichen, aber das ist nicht so relevant.

BEARBEITEN 2:
Es scheint, dass das, was ich will, so wie ich es brauche, nicht möglich ist (überprüfen Sie die Antworten von David Thornley und Blank Xavier und meine Kommentare). Vielen Dank für Ihre Zeit.

  • Bei C bin ich mir nicht sicher, aber C ++ kann in eine Datei ausgegeben und mit Breitengenauigkeit abgespielt werden. Wenn dies also auch in C möglich ist, lassen Sie es mich wissen, dann werde ich versuchen, mit einer Antwort zu helfen

    – TStamper

    16. April 2009 um 19:20 Uhr

  • Ist das nicht nur eine Frage der richtigen Einstellung?

    – Ungeheuer

    30. März 2017 um 18:33 Uhr

Benutzeravatar von dwc
dwc

Warum ist printf("%8d\n", intval); funktioniert bei dir nicht? Es sollte…

Sie haben die Formatzeichenfolgen für keines Ihrer “nicht funktionierenden” Beispiele angezeigt, daher bin ich mir nicht sicher, was ich Ihnen sonst noch sagen soll.

#include <stdio.h>

int
main(void)
{
        int i;
        for (i = 1; i <= 10000; i*=10) {
                printf("[%8d]\n", i);
        }
        return (0);
}

$ ./printftest
[       1]
[      10]
[     100]
[    1000]
[   10000]

BEARBEITEN: Antwort auf Klärung der Frage:

#include <math.h>
int maxval = 1000;
int width = round(1+log(maxval)/log(10));
...
printf("%*d\n", width, intval);

Die Breitenberechnung berechnet die logarithmische Basis 10 + 1, was die Anzahl der Ziffern ergibt. Die Phantasie * ermöglicht es Ihnen, die Variable für einen Wert in der Formatzeichenfolge zu verwenden.

Sie müssen immer noch das Maximum für einen bestimmten Lauf kennen, aber daran führt kein Weg vorbei, in keiner Sprache oder bei Bleistift und Papier.

Benutzeravatar von David Thornley
David Thornley

Ich suche das in meinem handlichen Harbison & Steele….

Bestimmen Sie die maximale Breite der Felder.

int max_width, value_to_print;
max_width = 8;
value_to_print = 1000;
printf("%*d\n", max_width, value_to_print);

Beachten Sie, dass max_width vom Typ sein muss int um mit dem Sternchen zu arbeiten, und Sie müssen es basierend darauf berechnen, wie viel Speicherplatz Sie haben möchten. In Ihrem Fall müssen Sie die maximale Breite der größten Zahl berechnen und 4 hinzufügen.

  • Das Problem ist, dass ich die größte Zahl nicht kenne, ich werde es nie wissen, bis ich sie erreiche. Und ich muss das spontan machen…

    – rfgamaral

    16. April 2009 um 20:20 Uhr

  • @Nazgulled: Mit anderen Worten, Sie stellen eine Frage, die per Definition unmöglich ist?

    – Michael myers

    16. April 2009 um 20:23 Uhr

  • Ich schätze… Aber ich wusste nicht, dass es unmöglich ist, bis einige Ihrer Antworten.

    – rfgamaral

    16. April 2009 um 21:50 Uhr

  • Ist das nicht nur eine Frage der richtigen Einstellung? So verstehe ich es zumindest.

    – Ungeheuer

    30. März 2017 um 18:33 Uhr

  • Angenommen, Sie lesen eine Datei ein und zeigen Zeilennummern an … Sie könnten die größte Zahl kennen. Lies bis zum Ende, zähle \n und kümmere dich dann um den Inhalt. Programme, die hinsichtlich des Speichers keine Einschränkungen haben, können einfach 2-GB-Dateien direkt in den Speicher laden, so dass es nur eine Reihe von Dateioperationen gibt.

    – Jimmi92

    24. Juli 2020 um 3:44 Uhr


    printf("%8d\n",1);
    printf("%8d\n",10);
    printf("%8d\n",100);
    printf("%8d\n",1000);

[I realize this question is a million years old, but there is a deeper question (or two) at its heart, about OP, the pedagogy of programming, and about assumption-making.]

Ein paar Leute, einschließlich eines Mods, haben vorgeschlagen, dass dies unmöglich ist. Und in einigen – einschließlich der offensichtlichsten – Kontexten ist es so. Aber es ist interessant zu sehen, dass das für das OP nicht sofort offensichtlich war.

Die Unmöglichkeit geht davon aus, dass der Contex eine aus C kompilierte ausführbare Datei auf einer zeilenorientierten Textkonsole (z. B. Konsole+sh oder X-term+csh oder Terminal+bash) ausführt, was eine sehr vernünftige Annahme ist. Aber die Tatsache, dass die “richtige” Antwort (“%8d“) war nicht gut genug für OP, während es auch nicht offensichtlich ist, dass es in der Nähe eine ziemlich große Dose Würmer gibt …

Betrachten Sie Curses (und seine vielen Varianten). Darin du kann auf dem “Bildschirm” navigieren und den Cursor herum “bewegen” und Teile (Fenster) der textbasierten Ausgabe “neu zeichnen”. In einem Curses-Kontext absolut wäre möglich; dh ein “Fenster” dynamisch skalieren, um eine größere Anzahl aufzunehmen. Aber selbst Curses ist nur eine Bildschirm-“Malerei”-Abstraktion. Niemand hat es vorgeschlagen, und wahrscheinlich zu Recht, weil es sich um eine Curses-Implementierung handelt in C bedeutet nicht, dass es “streng C” ist. Bußgeld.

Aber was bedeutet das wirklich? Damit die Antwort: “es ist unmöglich” richtig ist, würde es bedeuten, dass wir etwas über das Laufzeitsystem sagen. Mit anderen Worten, dies ist nicht theoretisch (wie in „Wie sortiere ich ein statisch zugewiesenes Array von ints?”), das als “geschlossenes System” erklärt werden kann, das jeden Aspekt der Laufzeit völlig ignoriert.

Aber in diesem Fall haben wir I/O: speziell die Implementierung von printf(). Aber das ist, wo es eine Gelegenheit gibt, etwas Interessanteres als Antwort gesagt zu haben (obwohl zugegebenermaßen der Fragesteller wahrscheinlich nicht ganz so tief gegraben hat).

Angenommen, wir verwenden einen anderen Satz von Annahmen. Angenommen, OP ist einigermaßen “clever” und versteht, dass es nicht möglich wäre, vorherige Zeilen in einem zeilenorientierten Stream zu bearbeiten (wie würden Sie die horizontale Position eines von einem Zeilendrucker ausgegebenen Zeichens korrigieren??). Nehmen wir auch an, dass OP nicht nur ein Kind ist, das an einer Hausaufgabe arbeitet und nicht merkt, dass es sich um eine “Trick” -Frage handelt, die eine Untersuchung der Bedeutung von “Stream-Abstraktion” herausfordern soll. Nehmen wir weiter an, OP hätte sich gefragt: „Warte … Wenn die Laufzeitumgebung von C die Idee von STDOUT unterstützt – und wenn STDOUT nur eine Abstraktion ist – warum ist es nicht genauso vernünftig, eine Terminal-Abstraktion zu haben, die 1) kann vertikales Scrollen, aber 2) unterstützt einen positionierbaren Cursor? Beide bewegen Text auf einem Bildschirm.”

Weil wenn das wäre die Frage, die wir zu beantworten versuchen, dann müssten Sie nur so weit schauen wie:

ANSI-Escape-Codes

um das zu sehen:

Fast alle Hersteller von Videoterminals haben herstellerspezifische Escape-Sequenzen hinzugefügt, um Operationen wie das Platzieren des Cursors an beliebigen Positionen auf dem Bildschirm auszuführen. Ein Beispiel ist das VT52-Terminal, mit dem der Cursor an einer x,y-Position auf dem Bildschirm platziert werden konnte, indem das ESC-Zeichen, ein Y-Zeichen und dann zwei Zeichen gesendet wurden, die numerische Werte darstellen, die der x,y-Position plus 32 entsprechen (also beginnend mit dem ASCII-Leerzeichen und Vermeidung der Steuerzeichen). Die Hazeltine 1500 hatte eine ähnliche Funktion, die mit ~, DC1 und dann mit einem Komma getrennten X- und Y-Positionen aufgerufen wurde. Während die beiden Terminals in dieser Hinsicht identische Funktionalität hatten, mussten unterschiedliche Steuersequenzen verwendet werden, um sie aufzurufen.

Das erste beliebte Videoterminal, das diese Sequenzen unterstützte, war das 1978 eingeführte Digital VT100. Dieses Modell war auf dem Markt sehr erfolgreich, was eine Vielzahl von VT100-Klonen hervorbrachte, von denen einer der frühesten und beliebtesten der viel günstigere Zenith Z war -19 im Jahr 1979. Andere waren Qume QVT-108, Televideo TVI-970, Wyse WY-99GT sowie optionale “VT100”- oder “VT103”- oder “ANSI”-Modi mit unterschiedlichem Kompatibilitätsgrad bei vielen anderen Marken. Die Popularität dieser Programme führte allmählich dazu, dass immer mehr Software (insbesondere Bulletin-Board-Systeme und andere Online-Dienste) annahm, dass die Escape-Sequenzen funktionierten, was dazu führte, dass fast alle neuen Terminals und Emulatorprogramme sie unterstützten.

Es hat möglich gewesen, bereits 1978. C selbst wurde 1972 “geboren”, und die K&R-Version wurde 1978 etabliert. Wenn es damals “ANSI”-Escape-Sequenzen gab, dann gibt es eine Antwort “in C”, wenn wir re bereit, auch zu fordern: “Nun, vorausgesetzt, Ihr Terminal ist VT100-fähig.” Übrigens, die Konsolen, die kein ANSI-Escapes unterstützen? Sie haben es erraten: Windows- und DOS-Konsolen. Aber auf fast jeder anderen Plattform (Unices, Vaxen, Mac OS, Linux) können Sie damit rechnen.

TL; DR – Es gibt keine vernünftige Antwort, die gegeben werden kann, ohne Annahmen über die Laufzeitumgebung zu treffen. Da die meisten Laufzeiten (es sei denn, Sie verwenden den Desktop-Computer-Marktanteil-der-80er-und-90er-Jahre, um “die meisten” zu berechnen) (seit der Zeit des VT-52!) Ich ziehe es an Ich denke nicht, dass es völlig gerechtfertigt ist zu sagen, dass es unmöglich ist – nur dass es eine ganz andere Größenordnung von Arbeit ist, damit es möglich ist, und nicht so einfach wie %8d… von dem es irgendwie so aussah, als wüsste das OP davon.

Wir müssen nur die Annahmen klären.

Und damit Sie nicht denken, dass E/A außergewöhnlich ist, dh dass wir uns nur um die Laufzeit (oder sogar die Hardware) kümmern müssen, graben Sie sich einfach in die Ausnahmebehandlung von IEEE 754-Fließkommazahlen ein. Für Interessierte:

Intel Fließkomma-Fallstudie

Laut Professor William Kahan von der University of California in Berkeley ereignete sich ein klassischer Fall im Juni 1996. Eine Satelliten-Heberakete namens Ariane 5 drehte kurz nach dem Start Wagenräder und zerstreute sich und eine Nutzlast im Wert von über einer halben Milliarde Dollar auf Französisch über einen Sumpf Guayana. Kahan stellte fest, dass die Katastrophe einer Programmiersprache zugeschrieben werden konnte, die die Standardspezifikationen für die Ausnahmebehandlung in IEEE 754 missachtete. Beim Start meldeten die Sensoren eine so starke Beschleunigung, dass dies zu einem Überlauf der Umwandlung in Ganzzahlen in der Software führte, die für die Neukalibrierung der Trägheit der Rakete bestimmt war Führung auf der Startrampe.

Benutzeravatar von Matt K
Matt K

Sie möchten also ein 8 Zeichen breites Feld mit Leerzeichen als Füllzeichen? Versuchen Sie “%8d”. Hier ist eine Referenz.

BEARBEITEN: Was Sie zu tun versuchen, kann nicht von printf allein gehandhabt werden, da es nicht weiß, was die längste Zahl ist, die Sie schreiben. Sie müssen die größte Zahl berechnen, bevor Sie printfs ausführen, und dann herausfinden, wie viele Ziffern Sie als Breite Ihres Felds verwenden möchten. Dann können Sie snprintf oder ähnliches verwenden, um sofort ein printf-Format zu erstellen.

char format[20];
snprintf(format, 19, "%%%dd\\n", max_length);
while (got_output) {
    printf(format, number);
    got_output = still_got_output();
}

  • printf(“%*d”, Breite, Wert) ist weniger Arbeit als das Erstellen des Formatstrings, wahrscheinlich weniger fehleranfällig und wahrscheinlich übersichtlicher. Aufgrund des zusätzlichen Arguments für printf() (denken Sie an viele variable Felder) könnte es möglicherweise langsamer sein, daher hat die von Ihnen veranschaulichte Technik in einigen Fällen einen Wert.

    – RBerteig

    16. April 2009 um 20:51 Uhr

Versuchen Sie, in eine Zeichenfolge zu konvertieren, und verwenden Sie dann „%4.4s“ als Formatbezeichner. Dies macht es zu einem Format mit fester Breite.

  • printf(“%*d”, Breite, Wert) ist weniger Arbeit als das Erstellen des Formatstrings, wahrscheinlich weniger fehleranfällig und wahrscheinlich übersichtlicher. Aufgrund des zusätzlichen Arguments für printf() (denken Sie an viele variable Felder) könnte es möglicherweise langsamer sein, daher hat die von Ihnen veranschaulichte Technik in einigen Fällen einen Wert.

    – RBerteig

    16. April 2009 um 20:51 Uhr

Soweit ich der Frage entnehmen kann, hängt die gewünschte Füllmenge von den Daten ab, die Sie haben. Dementsprechend besteht die einzige Lösung dafür darin, die Daten vor dem Drucken zu scannen, um das breiteste Datum herauszufinden und so einen Breitenwert zu finden, den Sie mit dem Asterix-Operator an printf übergeben können, z

loop over data - get correct padding, put into width

printf( "%*d\n", width, datum );

  • Dann kannst du es nicht. Wenn Sie ein Datum drucken müssen und was Sie drucken, hängt von folgenden Daten ab und Sie wissen nicht, was diese Daten sein werden, dann versuchen Sie eine unmögliche Aufgabe.

    Benutzer82238

    16. April 2009 um 21:16 Uhr

1390510cookie-checkWie richte ich eine solche Zahl in C aus?

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

Privacy policy