getNextCSV()
y setQuotedCSV()
: LibrerÃa para procesar archivos CSV.
Más...
#include <string>
#include <iostream>
#include <vector>
#include <stdlib.h>
Ir al código fuente de este archivo.
Definiciones | |
#define | Spanish_dox "Documentación en español" |
Documentación en español. | |
Funciones | |
void | setQuotedCSV (std::string &res, const std::string &value) |
Prepara value para ser grabado en un archivo CSV. | |
bool | getNextCSV (std::string &csv, std::istream &CIN) |
Obtiene del flujo de entrada CIN el siguiente valor CSV. | |
void | trim (std::string &str) |
Le elimina a "str" los blancos del principio y del final. | |
void | trimCSV (std::string &str) |
Convierte un campo CSV incorrecto en su probable valor correcto. | |
void | chop (std::string &str, char ch=0) |
Elimina ch si es el último caracter de str . |
getNextCSV()
y setQuotedCSV()
: LibrerÃa para procesar archivos CSV.
CSV: (Comma Separated Value). El formato CSV ha sido definido por IETF with RFC-4180.
char
; no ha sido probada con wchar_t
.trim()
o trimCSV()
.
getNextCSV()
.void
setQuotedCSV() y luego almacene la hilera resultante.CSV_line
es un empaque C++ para estas rutinas, pero requiere que no haya caracteres de fin de lÃnea ( Line Feed "\n"
) en los renglones del archivo CSV.
Definición en el archivo CSV.h.
#define Spanish_dox "Documentación en español" |
void setQuotedCSV | ( | std::string & | res, | |
const std::string & | value | |||
) |
Prepara value
para ser grabado en un archivo CSV.
res
.value
tiene espacios en blanco (whitespace).value
tiene comillas dobles.value
tiene comas ","
.'"'
dentro de value
por 2 comillas dobles
[""].char
; no ha sido probada con wchar_t
.
{{ // test::setQuotedCSV() std::string res; setQuotedCSV( res, "," ); assertTrue( res == "\",\"" ); // [","] setQuotedCSV( res, "2" ); assertTrue( res == "2" ); // [2] setQuotedCSV( res, "" ); assertTrue( res == "" ); // [] setQuotedCSV( res, "4,5" ); assertTrue( res == "\"4,5\"" ); // ["4,5"] setQuotedCSV( res, "K\"" ); assertTrue( res == "\"K\"\"\"" ); // ["K"""] setQuotedCSV( res, "\r\n" ); assertTrue( res == "\"\r\n\"" ); // ["\r\n"] }}
bool getNextCSV | ( | std::string & | csv, | |
std::istream & | CIN | |||
) |
Obtiene del flujo de entrada CIN
el siguiente valor CSV.
CIN
debiera estar abierto en modo std::ios::binary
pues los caracteres son extraÃdos uno por uno, usando CIN.get(ch)
.CIN
queda almacenado en csv
.char
, no ha sido probado para wchar_t
.csv
los caracteres finales (CR+LF or LF) ==> "\r\n"
o "\n"
.
"\n"
(LF -> LineFeed).{{ // test::getNextCSV() VEC.clear(); // std::vector<std::string> VEC; std::string csv; bool eol_CIN = false; // stop when the end of line is reached std::istringstream ist( str , std::ios::binary ); while ( ! eol_CIN && ! ist.fail() ) { // ! ist.eof() pitfall! eol_CIN = getNextCSV( csv, ist ); VEC.push_back( csv ); } return; // Using std::ios::binary ensures that no CR+LF chars are discarded }}
void trim | ( | std::string & | str | ) |
Le elimina a "str"
los blancos del principio y del final.
" \f\n\r\t\v"
.isspace(ch)
para determinar si una letra es o no es algún tipo de espacio whitespace.
{{ // test::trim() std::string str; str = " a b "; trim(str); assertTrue( str == "a b" ); str = " a\nb "; trim(str); assertTrue( str == "a\nb" ); str = ""; trim(str); assertTrue( str == "" ); str = "\r\t\n "; trim(str); assertTrue( str == "" ); str = " a b "; trim(str); assertTrue( str == "a b" ); str = " ab " ; trim(str); assertTrue( str == "ab" ); }}
void trimCSV | ( | std::string & | str | ) |
Convierte un campo CSV incorrecto en su probable valor correcto.
"str"
los blancos y comillas del principio y del final usando trim()
."str"
comienza y termina con comillas, sustituye cada pareja de comillas dobles
[""] por una sóla comilla simple
["].
En algunas ocasiones un archivo.csv tiene campos entre comillas que están precedidos por espacios en blanco. Esos campos CSV no cumplen con los requisitos definidos en la especificación RFC-4180 por lo que son extraÃdos por getNextCSV()
tal cual vienen, sin eliminar los espacios y sin sustituir las parejas de comillas dobles por comillas simples, como se muestra en el siguiente ejemplo en que los paréntesis cuadrados se usan en lugar de la comilla ["] para hacerlo más legible:
["zero", "if "" 1" , , " 3xt" \r\n] [....0.,........ 1..,2,.........3...] csv field getNextCSV() trimCSV() +------------------+----------------+----------+ | ["zero"] | [zero] | [zero] | | [, "if "" 1" ] | [ "if "" 1" ] | [if " 1] | | [, ] | [ ] | [] | | [, " 3xt" \r\n] | [ " 3xt" ] | [ 3xt] | +------------------+----------------+----------+
Por sentido común el programador esperarÃa que todas estas hileras fueran reconocidas, pero de acuerdo al RFC-4180 únicamente la primera es correcta. Al usar trimCSV()
en el valor obtenido al procesar esta lÃnea, se obtiene a fin de cuentas el valor esperado.
"\r"
o fines de lÃnea "\n"
seguramente son procesados de una manera diferente a lo esperado por getNextCSV()
, aún antes de ser recibidos como argumentos de trimCSV()
, por lo que es mejor no confiar en que esta rutina es una solución completa cuando se usan archivos.csv que no están escritos con apego estricto a la especificación RFC-4180.
{{ // test::trimCSV() CSV_line csv("\"zero\", \"if \"\" 1\" , , \" 3xt\" \r\f"); std::string s; s=csv[0]; assertTrue( s == "zero" ); trimCSV(s); assertTrue( s == "zero" ); s=csv[1]; assertTrue( s == " \"if \"\" 1\" " ); trimCSV(s); assertTrue( s == "if \" 1" ); s=csv[2]; assertTrue( s == " " ); trimCSV(s); assertTrue( s == "" ); s=csv[3]; assertTrue( s == " \" 3xt\" \r\f" ); trimCSV(s); assertTrue( s == " 3xt" ); }}
void chop | ( | std::string & | str, | |
char | ch | |||
) |
Elimina ch
si es el último caracter de str
.
ch
.
{{ // test::chop() std::string str; char ch; str = "12345"; assertTrue( str == "12345" ); chop(str,'0'); assertTrue( str == "12345" ); for ( ch='5'; ch != '0'; --ch ) { assertTrue( str[str.size()-1] == ch ); chop(str,ch); } assertTrue( str == "" ); chop(str,'3'); assertTrue( str == "" ); }}