EDITS ON THE BOTTOM (I wrote this as an edit rather than its own question because it is so related):
I am writing a CSV reader that should save all the values as ch
try this
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
//https://tools.ietf.org/html/rfc4180
char *getCSVField(FILE *fp, char separator, int *state){
int ch = fgetc(fp);
if(ch == EOF)
return NULL;
size_t size = 1, index = 0;
char *field = malloc(size);
bool quoted_in = false;
for(;ch != EOF; ch = fgetc(fp)){
if(ch == '"'){
if(quoted_in){
int prefetch = fgetc(fp);
if(prefetch == '"'){
ch = prefetch;
} else {
quoted_in = false;
ungetc(prefetch, fp);
continue;
}
} else {
quoted_in = true;
continue;
}
} else if(!quoted_in && (ch == separator || ch == '\n')){
break;
}
field[index++] = ch;
char *temp = realloc(field, ++size);
if(!temp){
perror("realloc:");
free(field);
exit(EXIT_FAILURE);
}
field = temp;
}
field[index] = 0;
*state = ch;
if(quoted_in){
fprintf(stderr, "The quotes is not closed.\n");
free(field);
return NULL;
}
return field;
}
char ***read_csv(const char *filename, size_t *rows, size_t *cols){
*rows = *cols = 0;
FILE *fp = fopen(filename, "r");
if(!fp){
fprintf(stderr, "%s can't open in %s\n", filename, __func__);
perror("fopen");
return NULL;
}
char *field;
int state;
size_t r = 0, c = 0;
char ***mat = NULL;
void *temp;
while(field = getCSVField(fp, ',', &state)){
if(c == 0){
mat = realloc(mat, (r + 1)*sizeof(*mat));
if(!mat){
fprintf(stderr, "realloc failed in %s\n", __func__);
exit(EXIT_FAILURE);
}
mat[r] = NULL;
}
mat[r] = realloc(mat[r], (c + 1)*sizeof(**mat));
if(!mat[r]){
fprintf(stderr, "realloc failed in %s\n", __func__);
exit(EXIT_FAILURE);
}
mat[r][c++] = field;
if(state == '\n' || state == EOF){
if(*cols == 0){
*cols = c;
} else if(c != *cols){
fprintf(stderr, "line %zu doesn't match number of columns in %s\n", r, filename);
exit(EXIT_FAILURE);
}
c = 0;
*rows = ++r;
}
}
fclose(fp);
return mat;
}
#include <ctype.h>
char *trim(char *s){
if(!s || !*s)
return s;
char *from, *to;
for(from = s; *from && isspace((unsigned char)*from); ++from);
for(to = s; *from;){
*to++ = *from++;
}
*to = 0;
while(s != to && isspace((unsigned char)to[-1])){
*--to = 0;
}
return s;
}
int main(void){
size_t rows, cols;
char ***mat = read_csv("simp.csv", &rows, &cols);
for(size_t r = 0; r < rows; ++r){
for(size_t c = 0; c < cols; ++c){
if(c)
putchar(',');
printf("%s", trim(mat[r][c]));
free(mat[r][c]);
}
puts("");
free(mat[r]);
}
free(mat);
return 0;
}