| Linux | MAC | Fenster |
|---|---|---|
RapidCSV ist eine benutzerfreundliche C ++-CSV-Parser-Bibliothek. Es unterstützt C ++ 11 (und später), ist nur Header und verfügt über eine grundlegende Testsuite.
Die Bibliothek wurde im Buch C ++ 20 für Programmierer vorgestellt.
Hier ist ein einfaches Beispiel, das eine CSV -Datei liest und die Spalte "Schließen" als Vektor von Floats erhalten.
colhdr.csv Inhalt:
Open,High,Low,Close,Volume,Adj Close
64.529999,64.800003,64.139999,64.620003,21705200,64.620003
64.419998,64.730003,64.190002,64.620003,20235200,64.620003
64.330002,64.389999,64.050003,64.360001,19259700,64.360001
64.610001,64.949997,64.449997,64.489998,19384900,64.489998
64.470001,64.690002,64.300003,64.620003,21234600,64.620003
Ex001.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
rapidcsv::Document doc ( " examples/colhdr.csv " );
std::vector< float > col = doc. GetColumn < float >( " Close " );
std::cout << " Read " << col. size () << " values. " << std::endl;
}Weitere Beispiele finden Sie im Abschnitt Weitere Beispiele. Das Testverzeichnis enthält auch viele einfache Verwendungsbeispiele.
RapidCSV wird mit C ++ 11 implementiert, um tragbar zu sein. Es wurde getestet an:
Kopieren Sie einfach src/rapidcsv.h in Ihr Projekt/integrieren Sie das Verzeichnis und schließen Sie es ein.
RapidCSV ist auch über VCPKG- und Conan -Paketmanager erhältlich.
Einige der folgenden Beispiele sind auch in examples/ Verzeichnissen angegeben und können direkt unter Linux und MacOS ausgeführt werden. Beispiel mit Ex001.cpp:
./examples/ex001.cpp
Standardmäßig behandelt Rapidcsv die erste Zeile als Spaltenkopfzeile, und die erste Spalte wird als Daten behandelt. Dies ermöglicht den Zugriff auf Spalten mithilfe ihrer Etiketten, nicht mit Zeilen oder Zellen (nur mit Indizes). Um die erste Spalte als Zeilenheader zu behandeln, muss man LabelParams verwenden und Probownameidx auf 0 einstellen.
colrowhdr.csv Inhalt:
Date,Open,High,Low,Close,Volume,Adj Close
2017-02-24,64.529999,64.800003,64.139999,64.620003,21705200,64.620003
2017-02-23,64.419998,64.730003,64.190002,64.620003,20235200,64.620003
2017-02-22,64.330002,64.389999,64.050003,64.360001,19259700,64.360001
2017-02-21,64.610001,64.949997,64.449997,64.489998,19384900,64.489998
2017-02-17,64.470001,64.690002,64.300003,64.620003,21234600,64.620003
Ex002.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
rapidcsv::Document doc ( " examples/colrowhdr.csv " , rapidcsv::LabelParams ( 0 , 0 ));
std::vector< float > close = doc. GetRow < float >( " 2017-02-22 " );
std::cout << " Read " << close . size () << " values. " << std::endl;
long long volume = doc. GetCell < long long >( " Volume " , " 2017-02-22 " );
std::cout << " Volume " << volume << " on 2017-02-22. " << std::endl;
}RowHDR.csv -Inhalt:
2017-02-24,64.529999,64.800003,64.139999,64.620003,21705200,64.620003
2017-02-23,64.419998,64.730003,64.190002,64.620003,20235200,64.620003
2017-02-22,64.330002,64.389999,64.050003,64.360001,19259700,64.360001
2017-02-21,64.610001,64.949997,64.449997,64.489998,19384900,64.489998
2017-02-17,64.470001,64.690002,64.300003,64.620003,21234600,64.620003
Ex003.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
rapidcsv::Document doc ( " examples/rowhdr.csv " , rapidcsv::LabelParams (- 1 , 0 ));
std::vector<std::string> row = doc. GetRow <std::string>( " 2017-02-22 " );
std::cout << " Read " << row. size () << " values. " << std::endl;
}Nohdr.csv Inhalt:
64.529999,64.800003,64.139999,64.620003,21705200,64.620003
64.419998,64.730003,64.190002,64.620003,20235200,64.620003
64.330002,64.389999,64.050003,64.360001,19259700,64.360001
64.610001,64.949997,64.449997,64.489998,19384900,64.489998
64.470001,64.690002,64.300003,64.620003,21234600,64.620003
Ex004.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
rapidcsv::Document doc ( " examples/nohdr.csv " , rapidcsv::LabelParams (- 1 , - 1 ));
std::vector< float > close = doc. GetColumn < float >( 5 );
std::cout << " Read " << close . size () << " values. " << std::endl;
long long volume = doc. GetCell < long long >( 4 , 2 );
std::cout << " Volume " << volume << " on 2017-02-22. " << std::endl;
}Für das Lesen von Dateien mit benutzerdefiniertem Trennzeichen (dh nicht Komma) muss man das Argument für Separatorparams angeben. Das folgende Beispiel liest eine Datei mit Semi-Colon als Trennzeichen.
Semi.CSV -Inhalt:
Date;Open;High;Low;Close;Volume;Adj Close
2017-02-24;64.529999;64.800003;64.139999;64.620003;21705200;64.620003
2017-02-23;64.419998;64.730003;64.190002;64.620003;20235200;64.620003
2017-02-22;64.330002;64.389999;64.050003;64.360001;19259700;64.360001
2017-02-21;64.610001;64.949997;64.449997;64.489998;19384900;64.489998
2017-02-17;64.470001;64.690002;64.300003;64.620003;21234600;64.620003
Ex005.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
rapidcsv::Document doc ( " examples/semi.csv " , rapidcsv::LabelParams ( 0 , 0 ),
rapidcsv::SeparatorParams ( ' ; ' ));
std::vector< float > close = doc. GetColumn < float >( " Close " );
std::cout << " Read " << close . size () << " values. " << std::endl;
long long volume = doc. GetCell < long long >( " Volume " , " 2017-02-22 " );
std::cout << " Volume " << volume << " on 2017-02-22. " << std::endl;
} Die interne Zelldarstellung in der Dokumentklasse verwendet STD :: String, und wenn andere Typen angefordert werden, werden Standardkonvertierungsroutinen verwendet. Alle Standardkonvertierungen sind relativ einfach, mit Ausnahme von char , für das Rapidcsv das (erste) Byte der Zelle als Charakter interpretiert. Das folgende Beispiel zeigt die unterstützten Datentypen.
colrowhdr.csv Inhalt:
Date,Open,High,Low,Close,Volume,Adj Close
2017-02-24,64.529999,64.800003,64.139999,64.620003,21705200,64.620003
2017-02-23,64.419998,64.730003,64.190002,64.620003,20235200,64.620003
2017-02-22,64.330002,64.389999,64.050003,64.360001,19259700,64.360001
2017-02-21,64.610001,64.949997,64.449997,64.489998,19384900,64.489998
2017-02-17,64.470001,64.690002,64.300003,64.620003,21234600,64.620003
Ex006.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
rapidcsv::Document doc ( " examples/colrowhdr.csv " , rapidcsv::LabelParams ( 0 , 0 ));
std::cout << doc. GetCell <std::string>( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < int >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < long >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < long long >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < unsigned >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < unsigned long >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < unsigned long long >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < float >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < double >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < long double >( " Volume " , " 2017-02-22 " ) << std::endl;
std::cout << doc. GetCell < char >( " Volume " , " 2017-02-22 " ) << std::endl;
}Man kann Conversion -Routinen überschreiben (oder neue hinzufügen), indem er toval () und/oder tostr () implementiert wird. Im Folgenden finden Sie ein Beispiel für eine überschreibende Int-Konvertierung, um stattdessen zwei Dezimalfixed-Punkt-Nummern bereitzustellen. Siehe auch Tests/Test035.CPP für einen übergeordneten Test toval () und tostr ().
Ex008.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
namespace rapidcsv
{
template <>
void Converter< int >::ToVal( const std::string& pStr, int & pVal) const
{
pVal = static_cast < int >( roundf ( 100 . 0f * std::stof (pStr)));
}
}
int main ()
{
rapidcsv::Document doc ( " examples/colrowhdr.csv " , rapidcsv::LabelParams ( 0 , 0 ));
std::vector< int > close = doc. GetColumn < int >( " Close " );
std::cout << " close[0] = " << close [ 0 ] << std::endl;
std::cout << " close[1] = " << close [ 1 ] << std::endl;
}Es ist auch möglich, Conversions pro Call-Basis zu überschreiben, was mehr Flexibilität ermöglicht. Dies ist im folgenden Beispiel dargestellt. Zusätzliche Verwendung von Conversion Override finden Sie in den Tests/Test063.cpp
Ex009.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
void ConvFixPoint ( const std::string& pStr, int & pVal)
{
pVal = static_cast < int >( roundf ( 100 . 0f * std::stof (pStr)));
}
struct MyStruct
{
int val = 0 ;
};
void ConvMyStruct ( const std::string& pStr, MyStruct& pVal)
{
pVal. val = static_cast < int >( roundf ( 100 . 0f * std::stof (pStr)));
}
int main ()
{
rapidcsv::Document doc ( " examples/colrowhdr.csv " , rapidcsv::LabelParams ( 0 , 0 ));
std::cout << " regular = " << doc. GetCell < int >( " Close " , " 2017-02-21 " ) << " n " ;
std::cout << " fixpointfunc = " << doc. GetCell < int >( " Close " , " 2017-02-21 " , ConvFixPoint) << " n " ;
auto convFixLambda = []( const std::string& pStr, int & pVal) { pVal = static_cast < int >( roundf ( 100 . 0f * stof (pStr))); };
std::cout << " fixpointlambda = " << doc. GetCell < int >( " Close " , " 2017-02-21 " , convFixLambda) << " n " ;
std::cout << " mystruct = " << doc. GetCell <MyStruct>( " Close " , " 2017-02-21 " , ConvMyStruct). val << " n " ;
} Zusätzlich zur Angabe eines Dateinamens unterstützt RapidCSV das Erstellen eines Dokuments aus einem Stream und indirekt durch Stringsstream aus einer Zeichenfolge. Dateiströme, die mit RapIDCSV verwendet werden, sollten in std::ios::binary -Modus geöffnet werden, um die volle Funktionalität zu ermöglichen. Hier ist ein einfaches Beispiel, das CSV -Daten aus einer Zeichenfolge liest:
Ex007.CPP -Inhalt:
# include < iostream >
# include < vector >
# include " rapidcsv.h "
int main ()
{
const std::string& csv =
" Date,Open,High,Low,Close,Volume,Adj Close n "
" 2017-02-24,64.529999,64.800003,64.139999,64.620003,21705200,64.620003 n "
" 2017-02-23,64.419998,64.730003,64.190002,64.620003,20235200,64.620003 n "
" 2017-02-22,64.330002,64.389999,64.050003,64.360001,19259700,64.360001 n "
" 2017-02-21,64.610001,64.949997,64.449997,64.489998,19384900,64.489998 n "
" 2017-02-17,64.470001,64.690002,64.300003,64.620003,21234600,64.620003 n "
;
std::stringstream sstream (csv);
rapidcsv::Document doc (sstream, rapidcsv::LabelParams ( 0 , 0 ));
std::vector< float > close = doc. GetColumn < float >( " Close " );
std::cout << " Read " << close . size () << " values. " << std::endl;
long long volume = doc. GetCell < long long >( " Volume " , " 2017-02-22 " );
std::cout << " Volume " << volume << " on 2017-02-22. " << std::endl;
}Standardmäßig löst Rapidcsv eine Ausnahme aus, wenn man versucht, auf nicht numerische Daten als numerischen Datentyp zuzugreifen, da die Ausnahmen der zugrunde liegenden Konvertierungsroutinen von der aufrufenden Anwendung grundsätzlich verbreitet werden.
Der Grund dafür ist, die Datenkorrektheit der Daten zu gewährleisten. Wenn man in der Lage sein möchte, Daten mit ungültigen Zahlen als numerische Datentypen lesen zu können, kann man Konverterparams verwenden, um den Konverter auf einen numerischen Wert zu konfigurieren. Der Wert ist konfigurierbar und standardmäßig ist er std :: numeric_limits :: signing_nan () für Float -Typen und 0 für Ganzzahltypen. Beispiel:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(),
rapidcsv::SeparatorParams(),
rapidcsv::ConverterParams( true ));RapidCSV liefert die Methoden GetColumnNames () und getRownames (), um die Spalten- und Zeilennamen abzurufen. Um zu überprüfen, ob ein bestimmter Spaltenname vorhanden ist, kann man beispielsweise tun:
rapidcsv::Document doc ( " file.csv " );
std::vector<std::string> columnNames = doc.GetColumnNames();
bool columnExists =
(std::find(columnNames.begin(), columnNames.end(), " A " ) != columnNames.end()); Standardmäßig wird RAPIDCSV automatisch dequotes zitierte Zellen (dh die Einkapselenden " -Scharaktere aus "example quoted cell" entfernt). Diese Funktionalität kann deaktiviert werden, indem pAutoQuote = false in SeparatorParams bestanden wird: Beispiel: Beispiel: Beispiel: Beispiel: Beispiel: Beispiel: Beispiel:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(),
rapidcsv::SeparatorParams( ' , ' /* pSeparator */ ,
false /* pTrim */ ,
rapidcsv:: sPlatformHasCR /* pHasCR */ ,
false /* pQuotedLinebreaks */ ,
false /* pAutoQuote */ ));Rapidcsv liest standardmäßig alle Zeilen, kann jedoch aufgerufen werden, um Kommentarzeilen zu ignorieren, beginnend mit einem bestimmten Zeichen: Beispiel:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(), rapidcsv::SeparatorParams(),
rapidcsv::ConverterParams(),
rapidcsv::LineReaderParams( true /* pSkipCommentLines */ ,
' # ' /* pCommentPrefix */ ));Unter Verwendung von LineArerparams ist es auch möglich, leere Zeilen zu überspringen, Beispiel:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(), rapidcsv::SeparatorParams(),
rapidcsv::ConverterParams(),
rapidcsv::LineReaderParams( false /* pSkipCommentLines */ ,
' # ' /* pCommentPrefix */ ,
true /* pSkipEmptyLines */ ));Die bevorzugte Codierung von Rapidcsv für den Nicht-ASCII-Text ist UTF-8. UTF-16 LE und UTF-16 BE können von Rapidcsv auf Systemen gelesen und geschrieben werden, in denen der CodeCVT-Header vorhanden ist. Definieren Sie HAS_CODECVT, bevor Sie Rapidcsv.h einbeziehen, um die Funktionalität zu ermöglichen. RAPIDCSV -Unit -Tests erkennt automatisch das Vorhandensein von CodeCVT und setzt HAS_CODECVT nach Bedarf fest. Siehe cmakelists.txt als Referenz. Bei Aktivierung wird die UTF-16-Kodierung einer geladenen Datei automatisch erkannt.
RapIDCSV kann mit FetchContent in ein CMake -Projekt aufgenommen werden. Weitere Informationen finden Sie im CMAKE -FetchContent -Beispielprojekt und insbesondere des Cmakelists.txt.
RapidCSV verwendet die von den landschema abhängigen Konvertierungsfunktionen, wenn die Float-Werte standardmäßig analysiert werden. Es ist möglich, RapidCSV so zu konfigurieren, dass sie das unabhängige Parsen von Lokalen verwenden, indem mNumericLocale in ConverterParams festgelegt wird
Die folgenden Klassen machen die Rapidcsv -Schnittstelle aus:
Rapidcsv verwendet CMake für seine Tests. Befehle zum Erstellen und Ausführen der Testsuite:
mkdir -p build && cd build && cmake -DRAPIDCSV_BUILD_TESTS=ON .. && make && ctest -C unit --output-on-failure && ctest -C perf --verbose ; cd -
Rapidcsv verwendet Doxygenmd, um seine Markdown -API -Dokumentation zu generieren:
doxygenmd src doc
RapidCSV verwendet Uncrustify, um eine konsistente Codeformatierung sicherzustellen:
uncrustify -c uncrustify.cfg --no-backup src/rapidcsv.h
Es gibt viele CSV -Parsers für C ++, zum Beispiel:
RapidCSV wird unter der BSD 3-Clause-Lizenz verteilt. Siehe Lizenzdatei.
Fehler, PRs usw. sind auf der GitHub -Projektseite willkommen https://github.com/d99kris/rapidcsv
C ++, C ++ 11, CSV -Parser, Comma -getrennte Werte, Einzelkopfbibliothek.