Skip to content

Instantly share code, notes, and snippets.

@alphaville
Last active December 11, 2015 12:58
Show Gist options
  • Save alphaville/4604442 to your computer and use it in GitHub Desktop.
Save alphaville/4604442 to your computer and use it in GitHub Desktop.
Read data from file and store them to a float* (array). C code.
// Header of this file:
#include "dataloader.h"
int load_vector_data(const char* filename, zvect* vector, int* length) {
*length = 0;
*vector = (zvect) malloc(sizeof (zreal) * ALLOCATION_CHUNK);
if (*vector == 0) return OUT_OF_MEM;
int allocated_rows = ALLOCATION_CHUNK;
u_short i = 0;
FILE* fr = fopen(filename, "r");
if (fr == NULL) return FILE_NOT_FOUND;
char line[LINE_SIZE];
while (fgets(line, LINE_SIZE, fr) != NULL) {
if (i >= allocated_rows) {
allocated_rows += ALLOCATION_CHUNK;
*vector = (zvect) realloc(*vector, sizeof (zreal) * allocated_rows);
if (*vector == 0) return OUT_OF_MEM;
}
strip_newline(line, LINE_SIZE);
(*vector)[i] = strtod(line, (char **) NULL);
i++;
}
*length = i;
*vector = realloc(*vector, sizeof (float) * i);
if (*vector == 0) return OUT_OF_MEM;
fclose(fr);
return 0;
}
static inline _Bool ismpt(char* text, const int size) {
short i = 0;
for (i = 0; i < size; i++) {
if (!isspace(text[i])) return false;
}
return true;
}
int load_matrix_data(const char* filename, zvect* matrix, int* nrows, int* ncols) {
*nrows = 0;
*ncols = 0;
const char dlm = ',';
const short word_size = 50;
FILE* fr = fopen(filename, "r");
if (fr == NULL) return FILE_NOT_FOUND;
char c;
*matrix = malloc(sizeof (zreal) * ALLOCATION_CHUNK);
int allocated_elements = ALLOCATION_CHUNK;
int i = 0;
int jPOS = 0;
char* number = (char*) malloc(sizeof (char) * word_size);
float x;
_Bool nColsFound = false;
_Bool last_was_delimiter = false, is_comment_line = false;
char comment_char = '!';
while ((c = fgetc(fr)) != EOF) {
if ('!'==c){
is_comment_line = true;
}
number = strndup(number, i);
if (!is_comment_line && (dlm == c || c == '\n') && !ismpt(number, i)) {
last_was_delimiter = true;
if ((*ncols) >= allocated_elements) {
allocated_elements += ALLOCATION_CHUNK;
*matrix = realloc(*matrix, sizeof (zreal) * allocated_elements);
}
x = strtof(number, (char**) NULL);
// printf("m[%d]=%f\n", jPOS, x);
(*matrix)[jPOS++] = x;
i = 0;
} else {
last_was_delimiter = false;
number[i++] = c;
}
if (c == '\n') {// New line met
is_comment_line = false;
(*nrows)++;
if (!nColsFound) {
nColsFound = true;
*ncols = jPOS;
}
}
}//end-while
if (jPOS == 0 && i > 0) {
*ncols = 1;
(*matrix)[0] = strtof(strndup(number, i), (char**) NULL);
}
if (jPOS != 0 && (*nrows) == 0) {
if (last_was_delimiter == false) {
*ncols = jPOS + 1;
} else {
*ncols = jPOS;
}
}
if (last_was_delimiter == false) {
(*matrix)[jPOS] = strtof(number, (char**) NULL);
}
(*nrows)++;
fclose(fr);
return 0;
}
int write_vector(const char* filename, const zvect data, const int length) {
FILE *file;
file = fopen(filename, "w");
if (file == NULL) {
return FILE_ERROR;
}
int i;
for (i = 0; i < length-1; i++) {
fprintf(file, "%f\n", data[i]);
}
fprintf(file, "%f", data[i]);
return fclose(file);
}
static void strip_newline(char *str, const int size) {
u_short i;
for (i = 0; i < size; ++i) {
if (str[i] == '\n') {
str[i] = '\0';
return;
}
}
}
/*
* File: DataLoader.h
* Author: Pantelis Sopasakis
*
* Created on January 22, 2013, 9:01 PM
*/
#ifndef DATALOADER_H
#define DATALOADER_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* ========= DEFINITIONS =========
*/
/**
* The exit code that is returned if the
* specified file is not found.
*/
#define FILE_NOT_FOUND 101
#define FILE_ERROR 102
#define OUT_OF_MEM 500
/**
* The size of the line that is parsed by
* fgets.
*/
#define LINE_SIZE 20
/**
* The number of lines that are incrementally
* allocated when reading from a file and writing
* to a float* (vector).
*/
#define ALLOCATION_CHUNK 100
/*
* ========= TYPES =========
*/
/**
* A Real Number.
*/
typedef float zreal;
/**
* A real vector.
*/
typedef zreal* zvect;
/*
* ========= FUNCTIONS =========
*/
/**
* Loads data from a file.
* Example of use:
* <pre>
* float* data;<br>
* int size = 0;<br>
* load_vector_data("huge_data", &data, &size);
* </pre>
* Benchmarking showed that a file of 14,400 lines is parsed
* in 1.50ms while a small file with 10 lines is parsed in
* approximately 0.01ms.
*
* @param filename
* Name of the file where to read the data from.
* @param data
* The vector with the data (pointer to float*).
* @param length
* The length of the vector.
*
*/
int load_vector_data(const char* filename, zvect* data, int* length);
int load_matrix_data(const char* filename, zvect* matrix, int* nrows, int* ncols);
int write_vector(const char* filename, const zvect data, const int length);
//int write_matrix(const char* filename, zvect* data, const int ncols);
/**
* Strips newline characters from strings.
* @param str
* @param size
*/
static void strip_newline(char *str, const int size);
static inline _Bool ismpt(char*, const int);
#ifdef __cplusplus
}
#endif
#endif /* DATALOADER_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment