zurück zum Artikel

Zeit in C++: Parser formatierter Eingaben

Rainer Grimm
Wecker, Zeit

(Bild: Kwangmoozaa/Shutterstock.com)

In diesem Artikel geht es um den Formatspezifizierer zum Verarbeiten von Eingaben.

Dieser Artikel ist der elfte in meiner ausführlichen Reise durch die Chrono-Erweiterung in C++20.

  1. Zeit in C++20: Einführung in die Chrono-Terminologie [1]
  2. Zeit in C++20: Einführung in die Chrono-Terminologie mit Zeitdauer und Zeitpunkt [2]
  3. Zeit in C++20: Neue Datentypen für die Tageszeit und das Kalenderdatum [3]
  4. Zeit in C++20: Kalendertermine erstellen [4]
  5. Zeit in C++20: Kalendertermine darstellen und prüfen [5]
  6. Zeit in C++20: Kalenderdaten abfragen und Ordinaldaten [6]
  7. Zeit in C++20: Details zu der Arbeit mit Zeitzonen [7]
  8. Zeitzonen in C++20: Online-Klassen [8]
  9. Zeit in C++20: Chrono I/O [9]
  10. C++20: Chrono I/O: Unformatiert und formatiert [10]
Modernes C++ – Rainer Grimm

Rainer Grimm ist seit vielen Jahren als Softwarearchitekt, Team- und Schulungsleiter tätig. Er schreibt gerne Artikel zu den Programmiersprachen C++, Python und Haskell, spricht aber auch gerne und häufig auf Fachkonferenzen. Auf seinem Blog Modernes C++ beschäftigt er sich intensiv mit seiner Leidenschaft C++.

Die Chrono-Bibliothek unterstützt formatierte Eingaben auf zwei Arten. Man kann die Funktionen std::chrono::from_stream oder std::chrono::parse verwenden. Beide Funktionen benötigen einen Eingabestrom und parsen die Eingabe entsprechend der Formatspezifikation in einen Zeitpunkt. Alle Formatspezifikationen außer %q für die Einheit, die entsprechend den Literalen für Zeitdauern angehängt werden, können verwendet werden.

std::chrono::from_stream hat Überladungen für die verschiedenen Uhrentypen.

Uhren

Kalenderdaten

Die verschiedenen Überladungen benötigen in der elementaren Form einen Eingabestrom is, einen Formatstring fmt und einen Zeitpunkt oder ein Kalenderobjekt chro – std::chrono::from_stream(is, fmt, chro). Das Chrono-Objekt aus dem Eingabestrom wird dann entsprechend dem Formatstring geparst.

Man kannst auch eine Abkürzung abb für eine Zeitzone und einen Offset der UTC-Zeit angeben: std::chrono::from_stream(is, fmt, chro, abb, off). Der Offset hat den Datentyp std::chrono::minutes.

Das Programm inputChrono.cpp verwendet eine formatierte Eingabe, um einen Zeitpunkt und ein Kalenderdatum aus einem Eingabestrom zu lesen.

// inputChrono.cpp

#include <chrono>
#include <iostream>
#include <string>
#include <sstream>

int main() {

    std::cout << '\n';

    std::chrono::sys_seconds timePoint;
    std::istringstream iStream1{"2021-08-11 21:49:35"};     //(1)
    std::chrono::from_stream(iStream1, "%F %T", timePoint); //(2)
    if (iStream1) std::cout << "timePoint: "  
      << timePoint << '\n';
    else std::cerr << "timepoint: Reading failed\n";

    std::chrono::year_month_day date1;
    std::istringstream iStream2{"11/08/21"};                //(3)
    std::chrono::from_stream(iStream2, "%x", date1);        //(4)
    if (iStream2) std::cout << "date1: "  << date1 << '\n';
    else std::cerr << "date1: Reading failed\n";

    std::chrono::year_month_day date2;
    std::istringstream iStream3{"11/15/21"};
    std::chrono::from_stream(iStream3, "%x", date2);        //(5)
    if (iStream3) std::cout << "date2: "  << date2 << '\n';
    else std::cerr << "date2: Reading failed\n";

    std::cout << '\n';

}

In den (1 und 2) entsprechen die Daten im Eingabestrom (iStream1) dem Formatstring ("%F %T"). Das Gleiche gilt für den Eingabestrom iStream2 (3) und den entsprechenden Formatstring "%x" (4). Im Gegensatz dazu gibt es keinen fünfzehnten Monat, und der Parse-Schritt in (5) schlägt fehl. Infolgedessen wird das Failbit des iStream3 gesetzt. Die Verwendung von iStream3 in einem booleschen Ausdruck ergibt false.

Analog zu std::chrono::from_stream kan man die Funktion std::chrono::parse zum Parsen von Eingaben verwenden. Der folgende Codeschnipsel zeigt ihre Gleichwertigkeit.

std::chrono::from_stream(is, fmt, chro)
is >> std::chrono::parse(fmt, chro)


Statt std::chrono::from_stream wird std::chrono::parse direkt auf dem Eingabestrom is aufgerufen. std::chrono::parse benötigt außerdem einen Format-String fmt und ein Chrono-Objekt chro.

Daher kann ich das vorherige Programm inputChrono.cpp mit std::chrono::from_stream direkt in das Programm inputChronoParse.cpp mit std::chrono::parse umschreiben.

// inputChronoParse.cpp

#include <chrono>
#include <iostream>
#include <string>
#include <sstream>

int main() {

    std::cout << '\n';

    std::chrono::sys_seconds timePoint;
    std::istringstream iStream1{"2021-08-11 21:49:35"};
    iStream1 >> std::chrono::parse("%F %T", timePoint);
    if (iStream1) std::cout << "timePoint: "  << timePoint << '\n';
    else std::cerr << "timepoint: Reading failed\n";

    std::chrono::year_month_day date1;
    std::istringstream iStream2{"11/08/21"};
    iStream2 >> std::chrono::parse("%x", date1);
    if (iStream2) std::cout << "date1: "  << date1 << '\n';
    else std::cerr << "date1: Reading failed\n";

    std::chrono::year_month_day date2;
    std::istringstream iStream3{"11/15/21"};
    iStream3 >> std::chrono::parse("%x", date2);
    if (iStream3) std::cout << "date2: "  << date2 << '\n';
    else std::cerr << "date2: Reading failed\n";

    std::cout << '\n';

}

Jetzt bin ich fertig mit meiner genauen Vorstellung der Chrono-Bibliothek. In meinem nächsten Artikel werde ich über Concurrency in C++20 schreiben. (rme [11])


URL dieses Artikels:
https://www.heise.de/-9769915

Links in diesem Artikel:
[1] https://www.heise.de/blog/Zeit-in-C-20-Einfuehrung-in-die-Chrono-Terminologie-9642462.html
[2] https://www.heise.de/blog/Zeit-in-C-20-Grundlegende-Chrono-Terminologie-mit-Zeitdauer-und-Zeitpunkt-9651792.html
[3] https://heise.de/-9664010
[4] https://heise.de/-9671530
[5] https://heise.de/-9684590
[6] https://heise.de/-9692091
[7] https://heise.de/-9705367
[8] https://www.heise.de/blog/Zeitzonen-in-C-20-Online-Klassen-9713375.html
[9] https://www.heise.de/blog/Zeit-in-C-20-Chrono-I-O-9723517.html
[10] https://www.heise.de/blog/C-20-Chrono-I-O-Unformatiert-und-formatiert-9759566.html
[11] mailto:rme@ix.de