'read csv file in C with commas inside strings
I have a csv file with commas as separator, but there are string values with commas inside, so mi code separate it too
char buffer[1024];
int row = 0;
int column = 0;
while (fgets(buffer,1024, fp)) {
column = 0;
row++;
if (row == 1)
continue;
char* value = strtok(buffer, ",");
while (value) {
if (column == 0) {
printf("Titulo :");
}
if (column == 1) {
printf("\tAutor :");
}
if (column == 2) {
printf("\tanio :");
}
if (column == 3) {
printf("\testante_numero :");
}
if (column == 4) {
printf("\testante_seccion :");
}
if (column == 5) {
printf("\tpiso :");
}
if (column == 6) {
printf("\tedificio :");
}
if (column == 7) {
printf("\tsede :");
}
printf("%s", value);
value = strtok(NULL, ",");
column++;
}
printf("\n");
}
// Close the file
fclose(fp);
Example of a row of the csv file: "Structure and Interpretation of Computer Programs","Abelson, Sussman, and Sussman",1996,4,"Lenguajes de Programacion",2,"B","Vina del Mar"
My output: Titulo :"Structure and Interpretation of Computer Programs" Autor :"Abelson anio : Sussman estante_numero : and Sus sman" estante_seccion :1996 piso :4 edificio :"Lenguajes de Programacion" sede :2"B""Vina del Mar"
How can i fix my code?
Solution 1:[1]
Fields in CSV file are delimited by commas and records are terminated by newlines. So, the idea is to read the file line by line, recognizing delimiting commas, but ignoring embedded commas.
The example below is not intended to be a perfect solution that will implement all the rules of a CSV specificication, but just an example how the file could be parsed with the information provided.
If the file includes a header row, than each field name could be read and stored in an array of strings, for a more general approach. Also, if some further operations on the data are required (perhaps sorting), structures could be used.
Some comments are included explaining the code.
#include <stdio.h>
#include <stdlib.h>
#define BUFF_SIZE 1024
#define NR_FIELDS 8
int main(void)
{
char buffer[BUFF_SIZE];
char *field[NR_FIELDS] = {"Titulo", "Autor", "Anio", "Estante numero", "Estante seccion", "Piso", "Edificio", "Sede"};
char *pos, *lastPos;
FILE *fp = fopen("file.csv", "r");
if (fp == NULL)
{
printf("Error opening the file.");
exit(1);
}
// read each line to a buffer
while (fgets(buffer, BUFF_SIZE, fp) != NULL)
{
int i = 0;
_Bool inString = 0;
pos = lastPos = buffer;
/* read characters from the buffer. If " is read, consider it beginning of the
string and ignore subsequent commas, until second " is read */
do
{
if (*pos == '\"')
inString = !inString;
/* if ',' is read or the end of the line is reached, while not inside a string,
consider it a field delimiter and print the field, preceded by field name */
if ((*pos == ',' || (*pos == '\0' && i == NR_FIELDS - 1)) && !inString)
{
printf("%s: %.*s", field[i++], pos - lastPos, lastPos);
if (*pos)
// add space between the fields if not at the end of the line
printf(" ");
lastPos = pos + 1;
}
} while (*pos++ && i < NR_FIELDS);
}
fclose(fp);
return 0;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
