CSV.h.
Más...
#include "CSV.h"
Ir al código fuente de este archivo.
Namespaces | |
| namespace | csv |
| Comma Separated Value (no usado en esta implementación). | |
Definiciones | |
| #define | COMMA ',' |
| #define | DQUOTE '"' |
| #define | LF '\n' |
| #define | CR '\r' |
Funciones | |
| bool | automataCSV (std::string &csv, std::istream &CIN) |
Obtiene del flujo de entrada CIN el siguiente valor CSV. | |
| void | singleDQUOTE (std::string &str) |
Sustituey cada letra DQUOTE doble por una solaletra DQUOTE en str. | |
| bool | getNextCSV (std::string &csv, std::istream &CIN) |
Obtiene del flujo de entrada CIN el siguiente valor CSV. | |
| void | setQuotedCSV (std::string &res, const std::string &value) |
Prepara value para ser grabado en un archivo 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) |
Elimina ch si es el último caracter de str. | |
CSV.h.
Definición en el archivo CSV.cpp.
| bool automataCSV | ( | std::string & | csv, | |
| std::istream & | CIN | |||
| ) |
Obtiene del flujo de entrada CIN el siguiente valor CSV.
CIN queda almacenado en csv.char, no ha sido probado para wchar_t.CIN.fail() o cuando CIN.eof().
| void singleDQUOTE | ( | std::string & | str | ) |
| 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 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"]
}}
| 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 = 0 | |||
| ) |
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 == "" );
}}
1.5.8