Reading .txt file and printing results - c

I'm trying to read the information I printed to a .txt file from a separate program, and display it in this new program. Although when I run the program, it says the file cannot be found. I suspect its my code, and not the file location as I have double checked my hard code, here is what I have so far, if anyone could point me in the right direction that would be great!
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 21
typedef struct data_slice
{
int t; // -> Time
float tp; // -> Valve pressure
float tf; // -> Sodium flow
float tt; // -> Sodium temp in Celsius
} data_slice;
void printIt(data_slice * data);
int main()
{
float num;
FILE *fptr;
data_slice data[ARRAY_SIZE];
if ((fptr = fopen("/Users/captainrogers/Documents/output_data.txt","r")) == NULL){
printf("Error! opening file");
// Program exits if the file pointer returns NULL.
exit(1);
}
fscanf(fptr,"%f \n", &num);
printIt(data);
fclose(fptr);
return 0;
}
void printIt(data_slice * data)
{
// Find the indice holding the time value of -10
int indice = 0;
for (int i = 0; i < ARRAY_SIZE; ++i)
{
if (data[i].t == -10)
{
indice = i;
break;
}
}
// Print results to screen
for (int i = 0, temp = indice; i < ARRAY_SIZE; ++i)
{
printf("%i\t %f\t %f\t %f\n", data[temp].t, data[temp].tp, data[temp].tf, data[temp].tt);
temp = (temp + 1) % ARRAY_SIZE;
}
}
Data I'm trying to print from .txt:
-10 595.000000 15.000000 167.000000
-9 557.000000 17.000000 168.000000
-8 634.000000 17.000000 114.000000
-7 656.000000 10.000000 183.000000
-6 561.000000 13.000000 139.000000
-5 634.000000 17.000000 124.000000
-4 672.000000 19.000000 155.000000
-3 527.000000 14.000000 166.000000
-2 656.000000 11.000000 188.000000
-1 661.000000 18.000000 141.000000
0 689.000000 17.000000 146.000000
1 624.000000 11.000000 104.000000
2 504.000000 20.000000 120.000000
3 673.000000 18.000000 147.000000
4 511.000000 12.000000 114.000000
5 606.000000 14.000000 171.000000
6 601.000000 13.000000 159.000000
7 602.000000 11.000000 127.000000
8 684.000000 10.000000 194.000000
9 632.000000 16.000000 139.000000
10 651.000000 13.000000 168.000000

fptr = fopen("C://Users//captainrogers//Documents//output_data.txt","r"))
try this code if you are sure your document is in the right file.

fopen("/Users/captainrogers/Documents/output_data.txt","r")
If the file can't be found, double-check your path. Maybe first try with the full path including the drive letter.
fscanf(fptr,"%f \n", &num);
Always check the return-value of fscanf(). "%f \n" is probably not the format string you want.
printIt(data);
Main problem: you never read any data into data[].

Related

Generic array printer not working for doubles type

I'm honestly going nuts here trying to understand why this generic array printer implementation is not working. Well, it works for an array of int's, but not for double's. What am I missing here?
void array_printer(FILE* stream, void* data, size_t data_type_size, size_t nr_rows, size_t nr_cols, char *format){
size_t offset = 0;
for (size_t r=0; r<nr_rows;++r){
for (size_t c=0; c<nr_cols; ++c){
fprintf(stream,format, *((int8_t*)data + offset*data_type_size));
//fprintf(stream,format, *((char*)data + offset*data_type_size)); // same behaviour
offset++;
}
fprintf(stream,"\n");
}
}
void array_print_double_2D(FILE* stream, double* data, size_t nr_rows, size_t nr_cols){
array_printer(stream, data, sizeof(double), nr_rows, nr_cols, " %lf ");
}
void array_print_int_2D(FILE* stream, int* data, size_t nr_rows, size_t nr_cols){
array_printer(stream, data, sizeof(int), nr_rows, nr_cols, " %d ");
}
int main(){
double *data_double = calloc(12, sizeof(double));
data_double[0] = 1;
data_double[1] = 2;
data_double[2] = 3;
array_print_double_2D(stdout, data_double, 3, 4);
/*
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000 what??
0.000000 0.000000 0.000000 0.000000
*/
int*data_int = calloc(12, sizeof(int));
data_int[0] = 1;
data_int[1] = 2;
data_int[2] = 3;
array_print_int_2D(stdout, data_int, 3, 4);
/*
1 2 3 0
0 0 0 0 correct
0 0 0 0
*/
Expression *(int8_t*)(data+...) will return int8_t which is not consistent with printf specifier " %lf ". This results in Undefined behavior.
The problem can be efficiently solved with macros that generate the printers.
#include <stdio.h>
#include <stdlib.h>
#define DEFINE_ARRAY_PRINT_2D(TYPE, FMT) \
void array_print_ ## TYPE ## _2D(FILE* stream, void* data, size_t nr_rows, size_t nr_cols) { \
size_t offset = 0; \
for (size_t r=0; r<nr_rows;++r){ \
for (size_t c=0; c<nr_cols; ++c){ \
fprintf(stream,FMT, ((TYPE*)data)[offset]); \
offset++; \
} \
fprintf(stream,"\n"); \
} \
}
// generate printers
DEFINE_ARRAY_PRINT_2D(int, " %d ")
DEFINE_ARRAY_PRINT_2D(double, " %lf ")
int main(){
double *data_double = calloc(12, sizeof(double));
data_double[0] = 1;
data_double[1] = 2;
data_double[2] = 3;
array_print_double_2D(stdout, data_double, 3, 4);
int *data_int = calloc(12, sizeof(int));
data_int[0] = 1;
data_int[1] = 2;
data_int[2] = 3;
array_print_int_2D(stdout, data_int, 3, 4);
return 0;
}
Produces output:
1.000000 2.000000 3.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
1 2 3 0
0 0 0 0
0 0 0 0
As expected.
You're casting the memory to int8_t* and dereferencing it, what were you expecting? I'd provide some sort of enumeration to distinguish between the typesand cast to the right one when needed.

Getting column data from file stream in C

I have a file which is written with a column of data (For example, "250\n 249\n...". Actually, there are 250 rows data with at most 15 digits in a row). I wish to get data from the different files and average them. However, I have no idea how could I get such a large amount of data with single column. I tried the following:
char str[80];\newline
FILE * abc;
abc=fopen("bromo.dat", "r");
fgets(str, 80, msd);
atof(str);
What I got was only the data from the first row. How could get the rest of the data?
You can use strtok to split the number in each line by space character. Then use the atof funcition as you used in your code to convert string to float number.
You should use 2D array to store all numbers in the file, and use another array to store the number in each line:
float number[250][15]; // maximum 250 line with at most 15 digits in each line
int number_each_line[250] = {0}; // the number of digits in each line
The complete program for test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[80];
float number[250][15];
int number_each_line[250] = {0};
FILE * fp;
fp =fopen("bromo.dat", "r");
if (!fp) {
return -1;
}
int i = 0;
while(fgets(str, 80, fp) && i < 250) {
int j = 0;
char *token = strtok(str, " ");
while(token != NULL) {
number[i][j] = atof(token);
j++;
token = strtok(NULL, " ");
}
number_each_line[i] = j;
i++;
}
// print first 10 lines in file
for(int k = 0; k < 10; k++) {
for(int j = 0; j < number_each_line[k]; j++) {
printf("%f ", number[k][j]);
}
printf("\n");
}
fclose(fp);
}
The output of test:
bromo.dat:
1.2 1 4 5
2.1 2 6 7 8
3.5 3 2 3 5.3
2.1 4 6 7 8
2.1 5 6 7 8
2.1 6 6 7 8
2.1 8 6 7 8
2.1 9 6 7 8
2.1 10 6 7 8
./test
1.200000 1.000000 4.000000 5.000000
2.100000 2.000000 6.000000 7.000000 8.000000
3.500000 3.000000 2.000000 3.000000 5.300000
2.100000 4.000000 6.000000 7.000000 8.000000
2.100000 5.000000 6.000000 7.000000 8.000000
2.100000 6.000000 6.000000 7.000000 8.000000
2.100000 8.000000 6.000000 7.000000 8.000000
2.100000 9.000000 6.000000 7.000000 8.000000
2.100000 10.000000 6.000000 7.000000 8.000000

Error with gsl_matrix_fscanf(file,matrix)

So right now I am simply trying to take a dummy data file,
1.30640 1
0.91751 1
0.49312 1
0.49312 0
1.79859 1
1.86360 1
0.12313 1
0.12313 0
-0.19091 1
1.82377 1
0.63205 1
0.63205 0
1.23357 1
0.62110 1
0.80438 1
and at the moment store it as a gal_matrix for manipulations later. Below is code which simply at the moment, given a data file name finds out how long it is (i.e. number of rows), initializes a gsl_matrix struct and then try to scan the text file into that matrix, called chain.
#include <stdio.h> // Needed for printf() and feof()
#include <math.h> // Needed for pow().
#include <stdlib.h> // Needed for exit() and atof()
#include <string.h> // Needed for strcmp()
#include <gsl/gsl_matrix.h> // Needed for matrix manipulations
/*------------ Defines -----------------------------------------------------------------*/
#define MAX_SIZE 10000000 // Maximum size of the time series array
#define NUM_LAG 1000 // Number of lags to calculate for
/*
*----------------------------------------------------------------------------------------
* Main program
*----------------------------------------------------------------------------------------
*/
int main(int argc, char* argv[]) {
//--------Initialization--------------------------------------------------------------
double ac_value; // computed autocorrelation value
int i,j; // Loop counter
long int N;
double mean, variance;
gsl_matrix * chains;
char filename[100];
FILE* in_file; // input file
FILE* out_file; // output file
int no_params; // number of parameters to calculate autocorrelation for
int first_column; // Which column first corresponds to a chain
int ch; // to determine number of samples in file
printf("-------------------------------------------------------------------------\n");
//--------Check that there are the correct number of arguments passed-----------------
if(argc != 4) {
printf("usage: ./auto_corr chainfile no_params first_column \n");
exit(1); // 0 means success typically, non-zero indicates an error
}
//--------Extract arguments-----------------------------------------------------------
sprintf(filename,"%s",argv[1]); // convert input file to string
in_file = fopen(filename,"rb"); // open input file for reading
no_params = atoi(argv[2]);
first_column = atoi(argv[3]);
//--------What is the number of samples in chain file?--------------------------------
N = 0; // Initialize count
while(!feof(in_file)) {
ch = fgetc(in_file);
if(ch == '\n'){
N++;
}
}
printf("Number of samples: %li\n", N); // print number of samples
if (N > MAX_SIZE) { // throw error if there are too many samples
printf("ERROR - Too many samples! MAX_SIZE = %i", MAX_SIZE);
exit(2);
}
//--------Generate a gsl matrix from the chains---------------------------------------
printf("%i\n", no_params);
chains = gsl_matrix_alloc(N, no_params); // allocate memory for gsl_matrix(rows, cols)
// print the matrix (for testing)
printf("Chain matrix \n");
for (int m=0;m<N;m++) { //rows
for (int n=0; n<no_params;n++) { // columns
printf("%f ",gsl_matrix_get(chains,m,n));
}
printf("\n");
}
// gsl_matrix_fprintf(stdout,chains,"%f"); // easy way to print, no formatting though
gsl_matrix_fscanf(in_file, chains); // read in chains to the gsl_matrix
fclose(in_file);
The error is occurring in the gsl_matrix_fscanf line, and the output I am seeing is
$ ./auto_corr auto_corr_test_data.dat 2 0
-------------------------------------------------------------------------
Number of samples: 15
2
Chain matrix
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
0.000000 0.000000
gsl: ./fprintf_source.c:165: ERROR: fscanf failed
Default GSL error handler invoked.
Abort trap: 6
I forgot to rewind the input file after I determined the number of rows.

assigning strtof value into 2D array in C

I'm trying to parse a CSV file into a 2D array in C. I want to make a matrix wit the structure :
typedef struct {
int row;
int col;
float **arr;
int numElements;
} Matrix;
The function I'm using takes in a dynamically allocated 2D array of floats, and is returned. I'm reading the values in using fgets, tokenizing each value between commas using strtok and then converting the string returned using strtof.
First, I made the 2D arrays dynamically and then pass them to the function to be filled in with values,
RMatrix->arr = make2DArray(RMatrix->row, RMatrix->col);
VMatrix->arr = make2DArray(VMatrix->row, VMatrix->col);
printf("RMatrix->arr : %p \n", RMatrix->arr);
printf("VMatrix->arr : %p \n", VMatrix->arr);
parseCSV(fpRMatrix, RMatrix->arr, RMatrix->row, RMatrix->col, &(RMatrix->numElements), INPUT_LENGTH);
printf("RMatrix parsed\n");
parseCSV(fpVMatrix, VMatrix->arr, VMatrix->row, VMatrix->col, &(VMatrix->numElements), INPUT_LENGTH);
printf("VMatrix parsed\n");
Below are the functions :
void parseCSV(FILE *fp, float **output, int row, int col, int *numElements ,int inputLength)
{
char *buffer;
int rowArr = 0;
printf("Output : %p \n", output);
buffer = (char*) malloc(inputLength * sizeof(char));
while(fgets(buffer, inputLength, fp)) {
char *p =strtok(buffer,",");
int colArr = 0;
float check = 0;
while(p)
{
printf("p now : %s \n", p);
check = strtof(p, (char**) NULL);
printf("check now : %f \n", check);
output[rowArr][colArr] = strtof(p, (char**) NULL);
*numElements += 1;
colArr++;
p = strtok('\0',",");
printf("output[%d][%d] : %f ", rowArr, colArr, output[rowArr][colArr]);
}
printf("\n");
rowArr++;
}
printf("numElements in the end : %d\n", *numElements);
free(buffer);
}
float **make2DArray(int row, int col)
{
float** arr;
float* temp;
arr = (float**)malloc(row * sizeof(float*));
temp = (float*)malloc(row * col * sizeof(float));
for (int i = 0; i < row; i++) {
arr[i] = temp + (i * row);
}
return arr;
}
The output :
Name : RMatrix
NumElements : 0
Rows : 2
Cols : 4
Name : VMatrix
NumElements : 0
Rows : 2
Cols : 4
RMatrix->arr : 0x11684d0
VMatrix->arr : 0x1168520
Output : 0x11684d0
p now : 1
check now : 1.000000
output[0][1] : 0.000000 p now : 2
check now : 2.000000
output[0][2] : 0.000000 p now : 3
check now : 3.000000
output[0][3] : 0.000000 p now : 4
check now : 4.000000
output[0][4] : 0.000000
p now : 5
check now : 5.000000
output[1][1] : 4.000000 p now : 6
check now : 6.000000
output[1][2] : 0.000000 p now : 7
check now : 7.000000
output[1][3] : 0.000000 p now : 8
check now : 8.000000
output[1][4] : 0.000000
numElements in the end : 8
RMatrix parsed
Output : 0x1168520
p now : 1
check now : 1.000000
output[0][1] : 0.000000 p now : 2
check now : 2.000000
output[0][2] : 0.000000 p now : 3
check now : 3.000000
output[0][3] : 0.000000 p now : 4
check now : 4.000000
output[0][4] : 0.000000
p now : 5
check now : 5.000000
output[1][1] : 4.000000 p now : 6
check now : 6.000000
output[1][2] : 0.000000 p now : 7
check now : 7.000000
output[1][3] : 0.000000 p now : 8
check now : 8.000000
output[1][4] : 0.000000
numElements in the end : 8
VMatrix parsed
As you can see, the strtof call succeeded (reflected in p and check variable) but not the assignment into the array.
I've only been using C for a month and I'm fascinated by it. However, it's obvious I need to learn more. I really appreciate your help :)
this
arr[i] = temp + (i * row);
should be
arr[i] = temp + (i * col);
since i = [0,row-1]

read in doubles from a text file (using C / Visual Studio)

I have a text file with numbers: two numbers on each row, separated by a space. Each pair of numbers represents an (x, y) co-ordinate. I am trying to write this in C, because it's the language I know, but I am working in Visual Studio 2010. The code I have is as follows:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#define MAXPOINTS 10
int _tmain(int argc, _TCHAR* argv[])
{
double points [MAXPOINTS];
int i;
for (i = 0; i < MAXPOINTS; i++) {
points[i] = 0.0;
}
FILE* pFile;
pFile = fopen ("points.txt","r");
if (pFile == NULL)
{
printf("Could not open file\n");
return 0;
}
rewind (pFile);
i = 0;
while (fscanf(pFile, "%f %f", &points[i], &points[i + 1]) == 2) {
printf("blah\n");
i = i + 2;
}
for (i = 0; i < MAXPOINTS; i++) {
printf("[%d] = %f\n", i, points[i]);
}
fclose (pFile);
return 0;
}
The output is:
blah
blah
blah
[0] = 0.000000
[1] = 0.000000
[2] = 0.000000
[3] = 0.000000
[4] = 0.000000
[5] = 0.000000
[6] = 0.000000
[7] = 0.000000
[8] = 0.000000
[9] = 0.000000
Where points.txt has three rows:
100 200
300 400
500 500
I can't figure out why the numbers aren't being read into the array.
Any ideas?
%f format requires pointer to float, and you give pointer to double.

Resources