Last active
December 11, 2015 12:58
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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