Error when I try to open a .dat file - c

I have a problem when I try to open a .dat file in a c code. Probably the error I made will be very obvious to some of you but I can't find it so I ask for your help.
The point of my code is to open the .dat file which contains 12.000.000 double numbers and store it in a cuDoubleComplex array which size will be 6.000.000 variables (the even variables of the .dat represents the real part and the odd variables the imaginary (I mean the order, not the value of the variable))
Here is an extract of my code:
#include "cuComplex.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
int main(void)
{
int n = 12000000; //12.000.000
int lse = n / 2;
double *data = (double *)malloc(12000000 * sizeof(double));
double *data2 = (double *)malloc(12000000 * sizeof(double));
FILE *f, *f2;
cuDoubleComplex *se, *se2;
f = fopen("ref_PRI20.dat", "r");
fread(data, sizeof(double), n, f);
fclose(f);
f2 = fopen("surv_PRI20.dat", "r");
fread(data2, sizeof(double), n, f2);
fclose(f2);
for (int a = 0; a < n; a++)
{
printf("%f\n", data2[a]);
}
se = (cuDoubleComplex*)malloc(lse * sizeof(cuDoubleComplex));
se2 = (cuDoubleComplex*)malloc(lse * sizeof(cuDoubleComplex));
for (int a = 0; a<n / 2; a++)
{
se[a].x = data[2 * a];
se[a].y = data[2 * a + 1];
se2[a].x = data2[2 * a];
se2[a].y = data2[2 * a + 1];
}
free(data);
free(data2);
}
I have added the printf lines and bucle just to check and all I get is "0,0000" as a value. Although when I continue with the programm the se and se2 arrays seems to get random values.
I know the size of the arrays is huge but I need to work with that amount of data.
I also have tried to work in matlab and I had no mistakes in there. This is the code that I used in matlab and everything was fine so I guess there is no problem with the .dat files but only with my code.
f = fopen ("ref_PRI20.dat", 'r');
Data = fread (f, 12e6, 'double');
fclose (f);
dat=(Data(1:2:end)+1i*Data(2:2:end)).';
Here's a scan of the input data so you can see the format. I hope it will help.
enter image description here
Any help will be appreciated.

No error checking on the original code for malloc or fopen.
Since a comment said the file was opened in a text reader and had commas between values, fscanf should be used to input the values instead of fread.
Since the values must be scanned one at a time there isn't a need for the data or data2 pointers.
Could not compile this as I don't have cuComplex.h
#include "cuComplex.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
int main(void)
{
int n = 12000000; //12.000.000
int lse = n / 2;
FILE *f, *f2;
cuDoubleComplex *se, *se2;
f = fopen("ref_PRI20.dat", "r");
f2 = fopen("surv_PRI20.dat", "r");
se = malloc(lse * sizeof(cuDoubleComplex));
se2 = malloc(lse * sizeof(cuDoubleComplex));
for (int a = 0; a < lse; a++)
{
if ( 1 != fscanf ( f, "%lf ,", &se[a * 2].x])) {
fprintf ( stderr, "could not scan double\n");
break;
}
if ( 1 != fscanf ( f, "%lf ,", &se[a * 2 + 1].y)) {
fprintf ( stderr, "could not scan double\n");
break;
}
if ( 1 != fscanf ( f2, "%lf ,", &se2[a * 2].x)) {
fprintf ( stderr, "could not scan double\n");
break;
}
if ( 1 != fscanf ( f2, "%lf ,", &se2[a * 2 + 1].y)) {
fprintf ( stderr, "could not scan double\n");
break;
}
}
fclose(f);
fclose(f2);
free ( se);
free ( se2);
return 0;
}

the following proposed code:
cleanly compiles
properly checks for and handles errors
reads the data directly into the struct.
Did not use the cuComplex.h file as that was not available.
avoided the use of 'magic' numbers
although the 'b' is not necessary in linux/unix, properly set the open mode to BINARY READ
documented why each header file is included.
eliminated all unnecessary variables and unnecessary calls to malloc()
eliminated all unnecessary data copying.
It may be desirable to read the data in a loop, using a 'moving window' until a 12000000 doubles are read. I'll let you add that feature, if necessary.
And now the proposed code:
#include <stdio.h> // fopen(), fread(), printf(), fprintf(), perror()
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc(), free()
#define N 12000000
struct cuDoubleComplex
{
double x;
double y;
};
int main(void)
{
struct cuDoubleComplex *data = malloc( (N>>1) * sizeof(double));
if( !data )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
struct cuDoubleComplex *data2 = malloc( (N>>1) * sizeof(double));
if( !data2 )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
FILE *f = fopen("ref_PRI20.dat", "rb");
if( !f )
{
perror( "fopen failed" );
free( data );
free( data2 );
exit( EXIT_FAILURE );
}
size_t nmemb = fread(data, sizeof(double), N, f);
if( nmemb != N )
{
fprintf( stderr, "read of first file only read %lu doubles\n", nmemb );
free( data );
free( data2 );
fclose( f );
exit( EXIT_FAILURE );
}
fclose(f);
FILE *f2 = fopen("surv_PRI20.dat", "rb");
if( !f2 )
{
perror( "fopen failed" );
free( data );
free( data2 );
exit( EXIT_FAILURE );
}
size_t nmemb2 = fread(data2, sizeof(double), N, f2);
if( nmemb2 != N )
{
fprintf( stderr, "read of second file only read %lu doubles\n", nmemb2 );
free( data );
free( data2 );
fclose( f2 );
exit( EXIT_FAILURE );
}
fclose(f2);
for (int a = 0; a < N; a++)
{
printf("%f\n", data2[a].y);
}
free(data);
free(data2);
} // end function: main

Related

C Program does nothing if I add a function call near the end

So I am currently trying to write a fairly simple program that takes a file as input, reads it, and lexes it (lexical analysis) (I will get to parsing and interpreting later)
I have written similar programs before that worked perfectly, but surprisingly, this one hangs when I add a function at the end.
The following works perfectly:
#include <stdio.h>
#include <stdlib.h>
#include "include/slex.h"
int main(void) {
// Read the file and save it into source.
printf("start\n");
FILE* fp = fopen("test.sl", "r");
printf("fileopen\n");
fseek(fp, 0, SEEK_END);
printf("seek\n");
char* source = malloc((ftell(fp) + 1) * sizeof (char)); // +1 because of the null terminator.
printf("allocation\n");
fseek(fp, 0, SEEK_SET);
char c;
int i = 0;
while ((c = fgetc(fp)) != EOF) {
source[i++] = c;
} // Iterate through every single character in the file and store it into source.
source[i] = '\0';
fclose(fp);
// Now lex the file;
printf("Lex\n");
lexer_t lexer;
printf("lex2\n");
lexer_init(&lexer, source);
printf("lex3\n");
/*
lex(&lexer);
printf("lex4");
tl_print(&lexer.tokens);
*/
}
But when I uncomment (hope that is an actual word) lex(&lexer), it just hangs. It does not print the previous statements.
The function lex is defined in slex.c and slex.c includes slex.h.
I compiled it with gcc -Wall Wextra -o sl main.c slex.c, and it does not give me any warning, nor any error.
void lex(lexer_t* lexer):
void lex(lexer_t* lexer) {
printf("lex"); // Debugging
// Some people would call this function "make_tokens", I will call it "lex".
while (lexer->current != '\0') {
if (lexer->current == '\n') {
token_t token = {.type = NEWLINE};
tl_append(&lexer->tokens, token);
}
if (isdigit(lexer->current)) {
token_t token = {.type = INT, .int_value = lex_integer(lexer)};
tl_append(&lexer->tokens, token);
}
else if (isalpha(lexer->current)) {
token_t token = {.type = ID, .id_value = lex_identifier(lexer)};
tl_append(&lexer->tokens, token);
}
}
}
I hope someone finds a solution to my problem, because I do not understand it.
Have a nice day and thank you.
And do not hesitate to ask if you need more information, just comment it and I will edit my question.
As Bill Lynch said, Adding fflush(stdout); before lex(&lexer); solved my issue. Thanks to everyone who came by this question, really appreciate your help. I wish you all a nice day.
Credit #Bill Lynch (first comment) who noted "app will [likely] hang" with infinite loop.
It's one thing to printf() to confirm operation. It's something else to check return codes and exit with helpful message.
Below is a rewritten (untested) version of your code using short name aliases to enhance clarity of what is being performed at different locations.
#include <stdio.h>
#include <stdlib.h>
#include "include/slex.h"
void lex( lexer_t *l ) {
fprintf( stderr, "Entered lex()\n" ); // debug
char c;
while( ( c = l->current ) != '\0' ) {
token_t t = { 0 };
if( c == '\n') t.type = NEWLINE;
// still infinite loop...
// what "advances" the pointer?? Credit #Craig Estey
else if( isdigit( c ) ) t.type = INT, t.int_value = lex_integer( l );
else if( isalpha( c) ) t.type = ID, t.id_value = lex_identifier( l );
else { // equivalent to "default:" in a "switch"
fprintf( stderr, "Un-lex-able char ('%c') encountered\n", c );
exit( EXIT_FAILURE );
}
tl_append( &l->tokens, t );
}
}
int main() {
char *fname = "test.sl";
FILE* fp = fopen( fname, "r" );
if( fp == NULL ) {
fprintf( stderr, "Failed to open %s\n", fname );
exit( EXIT_FAILURE );
}
fseek( fp, 0, SEEK_END );
size_t size = ftell( fp );
fseek(fp, 0, SEEK_SET);
fprintf( stderr, "Size %zu\n", size ); // debug
char *buf = malloc( (size + 1) * sizeof *buf ); // +1 because of the null terminator.
if( buf == NULL ) {
fprintf( stderr, "Failed to alloc block %zu\n", size + 1 );
exit( EXIT_FAILURE );
}
size_t nread = fread( buf, sizeof buf[0], size, fp );
if( nread != size ) {
fprintf( stderr, "Expected %zu. Read %zu\n", size. nread );
exit( EXIT_FAILURE );
}
fclose( fp );
buf[ nread ] = '\0';
lexer_t lexer;
lexer_init( &lexer, buf );
lex( &lexer );
// free( buf ); // Unsure if you refer back to original..
tl_print( &lexer.tokens );
return 0;
}
You can add as many optimistic "making progress" printf calls as you'd like. It's the pessimistic "not working" print statements that are needed to push forward.

How to assign a value to an array of structures in C?

There is a function load that reads an array of structures from a binary file and returns this array.It works correctly.But the problem is that I can not assign an array of structures the value that the load function returns.
struct tickets
{
char plane [7];
char zona [13];
int rate;
int cost;
};
struct tickets* load(char * filename)
{
FILE * file;
char *symbol;
int m = sizeof(int);
int n, i;
int *pti = (int *)malloc(m);
if ((file = fopen(filename, "r")) == NULL)
{
perror("Error occured while opening file");
}
symbol = (char *)pti;
while (m>0)
{
i = getc(file);
if (i == EOF) break;
*symbol = i;
symbol++;
m--;
}
n = *pti;
struct tickets* ptr = (struct tickets *) malloc(n * sizeof(struct tickets));
symbol = (char *)ptr;
while ((i= getc(file))!=EOF)
{
*symbol = i;
symbol++;
}
fclose(file);
return ptr;
}
int main(void)
{
char * filename = "p.dat";
struct tickets* ticket = NULL;
ticket = load(filename);
}
the following proposed code:
cleanly compiles
performs the desired functionality
properly checks for errors
informs the main() function as to how many instances of struct tickets were read
informs the user when any error occurs
cleans up after itself
eliminates one of the calls to malloc()
uses the function: fread() to avoid problems with little/big Endian
documents why each header file is included
assumes the ticket count (first 4 bytes of file) is in binary
incorporates appropriate horizontal and vertical spacing for readability
caveat: since no example input file posted, this code is not tested
and now, the proposed code:
#include <stdio.h> // perror(), NULL, FILE*, EOF,
// fopen(), fclose(), fread()
#include <stdlib.h> // malloc(), free(), exit(), EXIT_FAILURE
#define MAX_PLANE_LEN 7
#define MAX_ZONA_LEN 13
#define COUNT_LEN 4
struct tickets
{
char plane [ MAX_PLANE_LEN ];
char zona [ MAX_ZONA_LEN ];
int rate;
int cost;
};
struct tickets* load( char * filename, size_t * ticketCount )
{
FILE * fp;
if ( ! (fp = fopen( filename, "r" )) )
{
perror( "Error occured while opening file" );
exit( EXIT_FAILURE );
}
size_t bytesRead = fread( ticketCount, 1, COUNT_LEN, fp );
if( bytesRead != COUNT_LEN )
{
fprintf( stderr, "failed to read count of number of instances of 'struct tickets'\n" );
fclose( fp );
exit( EXIT_FAILURE );
}
struct tickets* ptr = malloc( *ticketCount * sizeof( struct tickets ) );
if( ! ptr )
{
perror( "malloc failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
for( size_t i = 0; i < *ticketCount; i++ )
{
size_t numBytes = fread( &(ptr[i]), 1, sizeof( struct tickets ), fp );
if( numBytes != sizeof( struct tickets ) )
{
perror( "read of a struct ticket failed" );
fclose( fp );
free( ptr );
exit( EXIT_FAILURE );
}
}
fclose( fp );
return ptr;
}
int main( void )
{
char * filename = "p.dat";
size_t ticketCount = 0;
struct tickets* ticket = load( filename, &ticketCount );
// ...
free( ticket );
}

is this right way of opening a .txt file

This part of code is responsiable for opening my data.txt file and reading a couple numbers from it (size of arrays and numbers to fill it with) but both Virtual Programming Lab and C say "can not find the program "" in executable files". I tried this way by writing a program what will only read 1 number from .txt and same error appeares so i guess im doing this completely wrong. Is there any other way of reading from .txt file? Thanks
Array* input() {
int x,y;
int i;
Array *p;
FILE *f=fopen("data.txt", "r");
p = (Array*) malloc(sizeof(Array));
fscanf(f, "&d",&x);
fscanf(f, "&d",&y);
p->n1 = x;
p->n2 = y;
p->p1 = (int*) malloc(sizeof(int) * p->n1);
p->p2 = (int*) malloc(sizeof(int) * p->n2);
for(i=0; i < p->n1; i++)
fscanf(f, "%d", &p->p1[i]);
for(i=0; i < p->n2; i++)
fscanf(f, "%d", &p->p2[i]);
fclose(f);
return p;
}
the following proposed code:
may cause the compiler to output: "untitled.c:114:9: warning: unused variable ‘ptrToArray’ [-Wunused-variable]"
performs the desired functionality
properly checks for I/O errors
properly cleans up after any I/O error
separates the definition of the struct from the typedef for that struct, for flexibility
the function: malloc() expects a parameter of type size_t. This results in several other changes being needed from int to size_t
for ease of readability and understanding: separates code blocks: for if else while do...while switch case default via a single blank line
for readability, inserts a space around C operators, inside parens, after commas, after semicolons, inside braces, inside brackets
follows the axiom: only one statement per line and (at most) one variable declaration per statement.
properly declares the parameter list for function: input() as void
for readability (by humans) consistently indents the code. indents after every opening brace '{'. Unindents before every closing brace '}'. Uses a indent width of 4 spaces.
for ease of readability and understanding: separates functions via 2 blank lines.
limits the scope of local variable i to the code block it is declared within rather than to the scope of the function: input()
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
struct array
{
size_t n1;
size_t n2;
int *p1;
int *p2;
};
typedef struct array ARRAY;
ARRAY* input( void )
{
size_t x;
size_t y;
ARRAY *p;
FILE *f = fopen( "data.txt", "r" );
if( !f )
{
perror( "fopen for reading data.txt failed" );
exit( EXIT_FAILURE );
}
p = malloc( sizeof(ARRAY) );
if( !p )
{
perror( "malloc for an instance of struct array failed" );
fclose( f );
exit( EXIT_FAILURE );
}
if( fscanf( f, "%zu", &x ) != 1 )
{
fprintf( stderr, "fscanf for first data from file failed\n" );
fclose( f );
free( p->p1 );
free( p->p2 );
free( p );
exit( EXIT_FAILURE );
}
if( fscanf( f, "%zu", &y ) != 1 )
{
fprintf( stderr, "fscanf for second data from file failed\n" );
fclose( f );
free( p );
exit( EXIT_FAILURE );
}
p->n1 = x;
p->n2 = y;
p->p1 = malloc(sizeof(int) * p->n1);
if( !p->p1 )
{
perror( "malloc failed for pointer 'p1'" );
free( p );
fclose( f );
exit( EXIT_FAILURE );
}
p->p2 = malloc(sizeof(int) * p->n2);
if( !p->p2 )
{
perror( "malloc failed for pointer 'p2'" );
free( p->p1 );
free( p );
fclose( f );
exit( EXIT_FAILURE );
}
for( size_t i=0; i < p->n1; i++ )
{
if( fscanf(f, "%d", &p->p1[i]) != 1 )
{
fprintf( stderr, "fscanf for %zu value in array 'p1' failed\n", i );
fclose(f);
free( p->p1 );
free( p->p2 );
free( p );
exit( EXIT_FAILURE );
}
}
for( size_t i=0; i < p->n2; i++ )
{
if( fscanf(f, "%d", &p->p2[i]) != 1 )
{
fprintf( stderr, "fscanf for %zu value in array 'p2' failed\n", i );
fclose(f);
free( p->p1 );
free( p->p2 );
free( p );
exit( EXIT_FAILURE );
}
}
fclose(f);
return p;
}
int main( void )
{
ARRAY *ptrToArray = input();
free( ptrToArray->p1 );
free( ptrToArray->p2 );
free( ptrToArray );
return 0;
}

How to open and read binary files from command line in a c program

I'm trying to write a code in C to read binary files from the command line using linux. The specifications on reading the file are as follows:
*The name of the input file is to be passed into the program as a command line argument.
*The program will open this binary file and read the first integer in the file. It will then dynamically create an array of floats of this size using the malloc function.
*The program will then read the floating point values and store them into this newly crated array.
The only thing I've been able to do successfully is open the file.I previously tried to allocate a block of memory by doing
file=double*malloc(30*sizeof(double));
But I kept getting errors and ran into some serious problems when trying to put file in the *ptr parameter of the fread fucntion
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
This is what I have so far:
#include <stdio.h>
int main ( int argc, char *argv[] )
{
if ( argc != 2 )
{
printf( "usage: %s filename", argv[0] );
}
else
{
FILE *file = fopen( argv[1], "r" );
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
int x;
while ( ( x = fgetc( file ) ) != EOF )
{
printf( "%c", x );
}
fclose( file );
}
}
}
Maybe something like this?
int size;
float *floatArray;
FILE *file = fopen( argv[1], "r" );
fread(&size, sizeof(int), 1, file);
floatArray = (float*) malloc(sizeof(float) * size);
fread(floatArray, sizeof(float), size, file);
for(int i = 0; i < size; i++)
{
printf("%d: %f\n", i+1, floatArray[i]);
}
#include <stdio.h>
#include <stdlib.h> /* for malloc() and exit() function */
int main(int argc, char* argv[])
{
FILE *file;
int i, n; /* the counter and num of floating point numbers */
float* val; /* pointer for storing the floating point values */
if(argc<2)
{
printf( "usage: %s filename", argv[0] );
exit(-1);
}
if((file = fopen( argv[1], "rb" )) ==NULL)
{
printf( "Could not open file.\n" );
exit(-2);
}
if(fread(&n, sizeof(int), 1, file)!=1)
{
printf( "Could not read data from file.\n" );
exit(-3);
};
if((val = malloc(n*sizeof(float)))==NULL)
{
printf( "Could not allocate memory for data.\n" );
exit(-4);
};
printf("Number of data values: %d\n", n);
if(fread(val, sizeof(float), n, file)!=n) /* read each floating point value one by one */
{
printf( "Could not read data from file.\n" );
exit(-5);
}
for(i=0; i<n; ++i)
{
printf("%f \t", val[i]); /* now print it */
}
free(val); /* free the allocated memory */
fclose(file); /* close the file */
return 0;
}
NB:
It is assumed that the size of int is same as in the data file and is not short, long or anything else.
Also, the endianness of the data file is assumed to be same as that of the machine on which this above code is run.

runtime error with malloc

#define MAXL 256
I think the problem with my code is that eventho numInput = 3, somehow, output[2] did not exist so that when I try to assign it, the program crash (just guessing).
Is there a way to check if ouput[2] exist? or maybe someone will be able to find out the real problem of my code, that would be awesome!
Any help would be greatly appreciated!
NOTE: The reason that I cast malloc is that it is expected by my lecturer.
Input strings are: 25 7 * 14 - 6 +
1 24 3 + * 41 -
2 37 4 + * 15 +
void processPostfixExp(const char * fileName)
{
char ** input = NULL;
double ** output = NULL;
int i = 0, numInput = 0;
char tempInput[MAXL] = {0};
FILE * pFile = NULL;
/* Get number of strings, check if file is readable and open file */
numInput = checkFile(fileName);
pFile = fopen(fileName, "r");
/* Allocate memory for the string storages and alert if fail */
input = (char**)malloc(numInput * sizeof(char*));
output = (double**)malloc(numInput * sizeof(double*));
if(!input || !output)
{
printf("Memory allocation failed.\n");
system("PAUSE");
exit(1);
}
/* Scan the file by lines and duplicate the string to input storage */
for(i = 0; i < numInput; ++i)
{
fgets(tempInput, MAXL, pFile);
tempInput[strlen(tempInput)-1] = '\0';
input[i] = strdup(tempInput);
//printf("\n%s", input[i]);
}
/* Close file and clear screen */
fclose(pFile);
system("CLS");
/* Call converter and display result */
printf("-------------------------------------------------------\n");
printf("\nPostfix expression evaluation:\n");
for(i = 0; i < numInput; ++i)
{
printf("input = %s", input[i]); /* i = 2 Printf SUCCESS */
*output[i] = evaluatePost(input[i]); /* i = 2 CRASH HERE */
/* I added a check at the top most of the evaluatePost(), program did not get to there */
//printf("\nCase %d: %s\nResult:%.2f\n", i + 1, input[i], *output[i]);
}
printf("\n");
printf("-------------------------------------------------------\n");
}
UPDATE:
so I added these lines and can confirm that output[2] does not exist... how is that possible? Please help, Thank you!
for(i = 0; i < numInput; ++i)
{
*output[i] = (double)i;
printf("output[%d] = %.1f\n", i, *output[i]);
}
The problem is that you have:
*output[i]
You have allocated numInput pointers to double, but the pointers themselves don't exist.
It looks like you want to allocate space not for pointers, but for doubles:
double *output;
…
output = (double*)malloc(numInput * sizeof(double));
I'm not sure what is wrong with your call to evaluatePost(), especially as you have not provided a prototype for that function.
However, overall, your code should look similar to the following:
in the future, please post code that (standalone) actually cleanly compiles
when you want help with a run time problem.
strongly suggest compiling with all warnings enabled.
For gcc, at a minimum, use '-Wall -Wextra -pedantic'
When handling a error, always cleanup allocated memory, open files, etc.
#define _POSIX_C_SOURCE (200809L)
#include <stdio.h>
#include <stdlib.h> // exit() and EXIT_FAILURE
#include <string.h> // memset() and strdup()
#define MAXL (256)
// prototypes
int checkFile( const char * );
double evaluatePost( char * );
void processPostfixExp(const char * fileName)
{
char **input = NULL;
double **output = NULL;
int i = 0;
int numInput = 0;
char tempInput[MAXL] = {0};
FILE *pFile = NULL;
/* Get number of strings, check if file is readable and open file */
numInput = checkFile(fileName);
if( NULL == (pFile = fopen(fileName, "r") ) )
{ // then fopen failed
perror( "fopen for input file failed" );
exit( EXIT_FAILURE );
}
/* Allocate memory for the string storages and alert if fail */
if( NULL == (input = malloc(numInput * sizeof(char*)) ) )
{ // then malloc failed
perror( "malloc for input failed" );
fclose( pFile );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
memset( input, 0x00, numInput*sizeof(char*) ); // to make later free() operation easy
if( NULL == (output = malloc(numInput * sizeof(double*)) ) )
{ // then malloc failed
perror( "malloc for output failed" );
fclose( pFile );
free( input );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
memset( output, 0x00, numInput * sizeof(double*) ); // to make later free() operation easy
/* Scan the file by lines and duplicate the string to input storage */
for(i = 0; i < numInput; ++i)
{
if( NULL == fgets(tempInput, MAXL, pFile) )
{ // then fgets failed
perror( "fgets for input file failed" );
fclose( pFile );
for( int j=0; j<numInput; j++ )
{
free( input[j] );
free( output[j] );
}
free( input );
free( output );
exit( EXIT_FAILURE );
}
// implied else, fgets successful
char * offset = NULL;
if( NULL != (offset = strstr( tempInput, "\n" )) )
{ // then newline found
*offset = '\0';
}
if( NULL == (input[i] = strdup(tempInput) ) )
{ // then strdup failed
perror( "strdup for input line failed" );
fclose( pFile );
for( int j=0; j<numInput; j++ )
{
free( input[j] );
free( output[j] );
}
free( input );
free( output );
exit( EXIT_FAILURE );
}
//printf("\n%s", input[i]);
} // end for
/* Close file and clear screen */
fclose(pFile);
system("CLS");
/* Call converter and display result */
printf("-------------------------------------------------------\n");
printf("\nPostfix expression evaluation:\n");
for(i = 0; i < numInput; ++i)
{
printf("input = %s", input[i]); /* i = 2 Printf SUCCESS */
*output[i] = evaluatePost(input[i]); /* i = 2 CRASH HERE */
/* I added a check at the top most of the evaluatePost(), program did not get to there */
//printf("\nCase %d: %s\nResult:%.2f\n", i + 1, input[i], *output[i]);
}
printf("\n");
printf("-------------------------------------------------------\n");
for( int j=0; j<numInput; j++ )
{
free( input[j] );
free( output[j] );
}
free( input );
free( output );
} // end function: processPostfixExp

Resources