EDITORIALS BELOW (I wrote this as an edit, not my own question, because it is so connected):
I am writing a CSV reader which should store all values as characters in a large multidimensional array. In previous posts, I was warned that I was too vague with my compressed code, so I'm going to post it more. I want to apologize for its length, as I am still trying to evaluate how the corresponding length looks on this site.
In the end, this program will become the headliner in the header file that I create to perform data analysis. The header files that I use for this program are as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
The problem I am facing is that the reader is working in the read_csv () function. I know this because of the printf () statements placed in this function. When I print f () a multidimensional array of characters "buffer" in main (), the data is not displayed correctly.
In main (), the first column will print correctly, but the next three will not. In addition, my goal is to read any CSV MxN file with cells carrying MAXIMUM of 20 characters. Generating generic code using malloc () is my next goal in this task.
My main () is structured as:
int main(){
FILE *f;
char fname[20];
int i, j;
printf("enter name of csv file : ") ;
scanf("%s",fname) ;
f = fopen(fname, "r");
int find_c_r[2];
int * pfrc = &find_c_r[0];
pfrc = find_col_row(f);
printf("Find_c_r[0] = %d \t Find_c_r[1] = %d\n", *pfrc, *(pfrc+1));
int numCol = *pfrc;
int numRow = *(pfrc+1);
char buffer[50][50][20];
for(j = 0 ; j < 50 ; j++){
for(i = 0 ; i < 10 ; i++){
memset(buffer[i][j],'\0', 20);
}
}
read_csv(f, numCol, numRow, buffer);
printf("\n\n");
for(j = 0 ; j < numRow ; j++){
for(i = 0 ; i < numCol; i++){
printf("[%d][%d]",i, j);
printf("_%s_ ",buffer[i][j]);
}
printf("\n");
}
printf("END OF PROGRAM.\n");
}
One part of this is the dynamic allocation of my "buffer" array. I'm not quite sure how malloc () is in this format.
main() find_col_row (FILE * f). , . int, CSV, :
int * find_col_row(FILE *f){
int numCol, numRow;
char c;
int new_line= 0;
int comma = 0;
int z = 0;
numCol = 0;
numRow = 0;
while (c != EOF) {
c = fgetc(f) ;
if(c == ','){
comma++;
}
if(c == ';'){
new_line++;
if(numCol == 0){
numCol = comma + 1;
}
}
}
numRow = new_line - 1;
int a[2] = {numCol, numRow};
int * pa = &a[0];
return pa;
}
- read_csv (...). - "" CSV "" " ":
void read_csv(FILE *f, int numCol, int numRow, char buffer[numCol][numRow][20])
{
char fname[100];
int i = 0, j = 0;
int c = 0,n = 0, z = 0;
if (f == NULL) {
printf("can't open file, %s\n", fname) ;
exit(1) ;
}
n = 0 ;
fseek(f, 0, SEEK_SET);
c = fgetc(f) ;
i = 0;
j = 0;
char temp[20];
memset(temp, '\0', 20);
int tc = 0;
int mv_temp = 0;
temp[tc] = c;
while (c != EOF) {
if(c == ','){
if(temp[0] == ' '){
for(mv_temp = 0 ; mv_temp < tc ; mv_temp++){
temp[mv_temp] = temp[mv_temp + 1];
}
}
strncpy(buffer[i][j], temp, 20);
i++;
tc = 0;
memset(temp, '\0', 20);
}else if(c == ';'){
if(temp[0] == ' '){
for(mv_temp = 0 ; mv_temp < tc ; mv_temp++){
temp[mv_temp] = temp[mv_temp + 1];
}
}
strncpy(buffer[i][j], temp, 20);
j++;
i = 0;
tc = 0;
memset(temp, '\0', 20);
c = fgetc(f);
}else{
temp[tc] = c;
tc++;
}
c = fgetc(f);
}
for(j = 0 ; j < numRow ; j++){
for(i = 0 ; i < numCol; i++){
printf("[%d][%d]",i, j);
printf("_%s_ ",buffer[i][j]);
}
printf("\n");
}
}
CSV , CSV, . scanf() .
simp.csv
, : , , , . :
OFF_FORM,FORM_VAR, DN, DIST;
DEUCE,RIGHT, 1, 10;
DEUCE,LEFT, 2, 7;
TRIO,RIGHT, 3, 3;
TREY,LEFT, 1, 10;
TRIO,RODDY, 1, 10;
TREY,LION, 2, 3;
DEEP,LEFT, 1, 10;
DEUCE,LION, 2, 15;
DEUCE,RIGHT, 3, 4;
DEEP,RODDY, 1, 10;
TREY,RIGHT, 1, 10;
TRIO,RAM, 2, 8;
TRIO,RAM, 3, 8;
DEEP,ROCK, 1, 10;
DEUCE,LION, 1, 10;
TRIO,LOUIE, 1, 10;
TRIO,RIGHT, 2,4;
DEUCE,RIGHT, 3, 6;
DEUCE,LION, 4, 2;
TREY,LION,1,10;
, . , , . , . , , .
////////////////////////////////
////////////////////////////////
:
, @BLUEPIXY , . , , , . , , .
#ifndef bp_csv_reader
#define bp_csv_reader
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
char *csv_get_field(FILE *fp, char separator, int *state)
char ***csv_read(const char *filename, size_t *rows, size_t *cols)
char *csv_trim(char *s)
#endif
csv.c :
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "csv.h"
char *csv_get_field(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 ***csv_read(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 = csv_get_field(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 *csv_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;
}
:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <csv.h>
int main(void){
size_t rows, cols;
char ***mat = csv_read("simp.csv", &rows, &cols);
size_t r, c;
for(r = 0; r < rows; ++r){
for(c = 0; c < cols; ++c){
if(c)
putchar(',');
printf("%s", csv_trim(mat[r][c]));
free(mat[r][c]);
}
puts("");
free(mat[r]);
}
free(mat);
return 0;
}
, , . , , . , . int it terminal:
acom test_csv.c csv.c -I. csv.h
, .
In file included from test_cesv.c:5:0:
./csv.h: In function ‘csv_get_field’:
./csv.h:15:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘char’
char *csv_trim(char *s)
^
test_cesv.c:142:1: error: expected ‘{’ at end of input
}
^
In file included from csv.c:5:0:
csv.h: In function ‘csv_get_field’:
csv.h:15:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘char’
char *csv_trim(char *s)
^
csv.c:55:67: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
char ***csv_read(const char *filename, size_t *rows, size_t *cols){
^
csv.c:105:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token
char *csv_trim(char *s){
^
csv.c:120:1: error: expected ‘{’ at end of input
}
^
csv.h: In function ‘csv_get_field’:
csv.h:15:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘char’
char *csv_trim(char *s)
^