| Linux | Mac | Windows |
|---|---|---|
O RapIDCSV é uma biblioteca de analisador C ++ C ++ C ++. Ele suporta C ++ 11 (e posterior), é somente para o cabeçalho e vem com um conjunto de testes básicos.
A biblioteca foi apresentada no livro C ++ 20 para programadores.
Aqui está um exemplo simples lendo um arquivo CSV e obtendo a coluna "Close" como um vetor de carros alegóricos.
Conteúdo colhdr.csv:
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
conteúdo ex001.cpp:
# 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;
}Consulte a seção mais exemplos abaixo para obter mais exemplos. O diretório de testes também contém muitos exemplos de uso simples.
O RapIDCSV é implementado usando C ++ 11 com a intenção de ser portátil. Foi testado em:
Basta copiar o SRC/Rapidcsv.h para o seu projeto/incluir diretório e incluí -lo.
O RapIDCSV também está disponível via gerentes de pacotes VCPKG e Conan.
Vários dos exemplos a seguir também são fornecidos nos examples/ diretório e podem ser executados diretamente em Linux e MacOS. Exemplo executando ex001.cpp:
./examples/ex001.cpp
Por padrão, o RapIDCSV trata a primeira linha como cabeçalhos de coluna e a primeira coluna é tratada como dados. Isso permite acessar colunas usando seus rótulos, mas não linhas ou células (apenas usando índices). Para tratar a primeira coluna como cabeçalhos de linha, é preciso usar o LabelParams e definir o PROWNAMEIDX como 0.
Conteúdo Colrowhdr.csv:
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
Conteúdo Ex002.CPP:
# 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;
}Conteúdo RowHdr.CSV:
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
Conteúdo Ex003.CPP:
# 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 Conteúdo:
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
Conteúdo Ex004.CPP:
# 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;
}Para leitura de arquivos com separador personalizado (ou seja, vírgula), é preciso especificar o argumento do SeparatorParams. O exemplo a seguir lê um arquivo usando o Semi-Colon como separador.
conteúdo semi.csv:
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
Conteúdo Ex005.CPP:
# 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;
} A representação da célula interna na classe de documentos está usando a STD :: String e quando outros tipos são solicitados, as rotinas de conversão padrão são usadas. Todas as conversões padrão são relativamente seguidas, com exceção de char , para o qual o RapIDCSV interpreta o byte da célula (primeiro) como personagem. O exemplo a seguir ilustra os tipos de dados suportados.
Conteúdo Colrowhdr.csv:
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
conteúdo ex006.cpp:
# 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;
}Pode -se substituir as rotinas de conversão (ou adicionar novas) implementando ToVal () e/ou ToStr (). Abaixo está um exemplo que substitui a conversão int, para fornecer dois números decimais de ponto fixo. Consulte também Testes/Test035.CPP para um teste substituindo ToVal () e ToSTR ().
conteúdo ex008.cpp:
# 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;
}Também é possível substituir as conversões por chamada, permitindo mais flexibilidade. Isso é ilustrado no exemplo a seguir. O uso adicional de substituição de conversão pode ser encontrado nos testes de teste/test063.cpp
Ex009.CPP Conteúdo:
# 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 " ;
} Além de especificar um nome de arquivo, o RapIDCSV suporta a construção de um documento a partir de um fluxo e, indiretamente através do StringStream, a partir de uma string. Os fluxos de arquivos usados com o RapIDCSV devem ser abertos no modo std::ios::binary para ativar a funcionalidade completa. Aqui está um exemplo simples de ler dados de CSV de uma string:
conteúdo ex007.cpp:
# 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;
}Por padrão, o RapIDCSV gera uma exceção se tentar acessar dados não numéricos como um tipo de dados numéricos, pois basicamente propaga as exceções das rotinas de conversão subjacentes ao aplicativo de chamada.
O motivo disso é garantir a correção dos dados. Se alguém quiser ler dados com números inválidos como tipos de dados numéricos, pode usar o ConverterParams para configurar o conversor para padrão para um valor numérico. O valor é configurável e, por padrão, é std :: numeric_limits :: Signaling_nan () para tipos de flutuação e 0 para tipos inteiros. Exemplo:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(),
rapidcsv::SeparatorParams(),
rapidcsv::ConverterParams( true ));O RapIDCSV fornece os métodos getColumnNames () e getRowNames () para recuperar os nomes da coluna e da linha. Para verificar se existe um nome de coluna específico, pode -se, por exemplo, fazer:
rapidcsv::Document doc ( " file.csv " );
std::vector<std::string> columnNames = doc.GetColumnNames();
bool columnExists =
(std::find(columnNames.begin(), columnNames.end(), " A " ) != columnNames.end()); Por padrão, o RAPIDCSV desencadeia automaticamente as células citadas (ou seja, remove os caracteres que encapsularam " "example quoted cell" ). Essa funcionalidade pode ser desativada passando pAutoQuote = false em SeparatorParams , exemplo:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(),
rapidcsv::SeparatorParams( ' , ' /* pSeparator */ ,
false /* pTrim */ ,
rapidcsv:: sPlatformHasCR /* pHasCR */ ,
false /* pQuotedLinebreaks */ ,
false /* pAutoQuote */ ));O RapidCSV lê todas as linhas por padrão, mas pode ser chamado para ignorar as linhas de comentários começando com um personagem específico, exemplo:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(), rapidcsv::SeparatorParams(),
rapidcsv::ConverterParams(),
rapidcsv::LineReaderParams( true /* pSkipCommentLines */ ,
' # ' /* pCommentPrefix */ ));Usando o LineReadeRParams, também é possível pular linhas vazias, exemplo:
rapidcsv::Document doc ( " file.csv " , rapidcsv::LabelParams(), rapidcsv::SeparatorParams(),
rapidcsv::ConverterParams(),
rapidcsv::LineReaderParams( false /* pSkipCommentLines */ ,
' # ' /* pCommentPrefix */ ,
true /* pSkipEmptyLines */ ));A codificação preferida do RapidCSV para texto não-ASCII é UTF-8. UTF-16 LE e UTF-16 podem ser lidos e escritos pelo RapidCSV em sistemas em que o cabeçalho do codecvt está presente. Definir has_codecvt antes de incluir o rapidcsv.h para ativar a funcionalidade. Os testes da unidade RapIDCSV detectam automaticamente a presença de codecvt e define has_codecvt conforme necessário, consulte cmakelists.txt para referência. Quando ativado, a codificação UTF-16 de qualquer arquivo carregada é detectada automaticamente.
O RapIDCSV pode ser incluído em um projeto CMake usando o FetchContent. Consulte o projeto Cmake FetchContent Exemplo e, em particular, seus cmakelists.txt.
O RapIDCSV usa funções de conversão dependentes de localidade ao analisar valores de flutuação por padrão. É possível configurar o RAPIDCSV para usar a análise independente da localidade definindo mNumericLocale em ConverterParams , veja por exemplo testes/test087.cpp
As classes a seguir compõem a interface RAPIDCSV:
O RapIDCSV usa o CMake para seus testes. Comandos para construir e executar o conjunto de testes:
mkdir -p build && cd build && cmake -DRAPIDCSV_BUILD_TESTS=ON .. && make && ctest -C unit --output-on-failure && ctest -C perf --verbose ; cd -
O RapidcSV usa doxygenmd para gerar sua documentação da API de marcação:
doxygenmd src doc
O RapidcSV usa a Uncrustify para garantir formatação consistente de código:
uncrustify -c uncrustify.cfg --no-backup src/rapidcsv.h
Existem muitos analisadores CSV para C ++, por exemplo:
O RapIDCSV é distribuído sob a licença de cláusulas 3 do BSD. Consulte o arquivo de licença.
Bugs, PRs, etc são bem -vindos na página do projeto do Github https://github.com/d99kris/rapidcsv
C ++, C ++ 11, analisador CSV, valores separados por vírgula, biblioteca de cabeçalho único.