Do you really need linked lists? Do you really need to inform the number of polynomials and the number of coefficients?
Here's an example using a file like this:
Code:
# test.txt: 3 Polynomials defined below:
1 2 3
3.14 2.72 10 1
# line above is blank
3 2 1 4 # line with polynomial and commentary.
And here's a program to parse this:
Code:
// sys.c
//
// This program reads lines, ignoring empty ones and comments (marked with #)...
// MORE work needed. For instance, to check if a line has an invalid syntax.
//
// definition needed for GNU's basename() routine.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h> // realloc() and free(). and EXIT_??? constants.
#include <string.h> // basename(), strtok(), strchr().
// "list" of coefficients.
typedef struct coeff_T
{
unsigned int numcoeffs;
double *coeffs;
} coeff_T;
// Get coefficients from a line.
int get_coeffs( coeff_T *, char *, unsigned int );
int main( int argc, char *argv[] )
{
FILE *f;
char *line;
size_t line_size;
coeff_T *polys_listp = NULL;
unsigned int numpolys = 0, i;
// test command line arguments.
if ( argc != 2 )
{
fprintf( stderr, "Usage: %s <file>\n", basename( *argv ) );
return EXIT_FAILURE;
}
// tries to open the input file.
if ( ! ( f = fopen( *++argv, "r" ) ) )
{
fprintf( stderr, "ERROR: Cannot open '%s' file.\n", *argv );
return EXIT_FAILURE;
}
// Read the lines (dynamic allocated)...
line = NULL;
line_size = 0;
while ( getline( &line, &line_size, f ) != -1 )
{
coeff_T coeffs;
// if there are coefficients, update the polynomials list.
if ( get_coeffs( &coeffs, line, numpolys + 1 ) )
{
coeff_T *p;
// Increase polynomials list size.
if ( ! ( p = realloc( polys_listp, sizeof(coeff_T)*(numpolys + 1) ) ) )
{
fputs( "ERROR: Cannot reallocate polynomials list.\n", stderr );
return EXIT_FAILURE;
}
polys_listp = p;
polys_listp[numpolys++] = coeffs;
}
// free the line and prepare for the next one.
free( line );
line = NULL;
line_size = 0;
}
fclose( f );
// Show the polynimials. Expoents in reverse order.
for ( i = 0; i < numpolys; i++ )
{
unsigned int j;
printf( "%u: ", i + 1 );
for ( j = 0; j < polys_listp[i].numcoeffs; j++ )
printf( "%gx^%u ", polys_listp[i].coeffs[j], polys_listp[i].numcoeffs - j - 1 );
putchar('\n');
}
return EXIT_SUCCESS;
}
// numpoly used only to report error...
int get_coeffs( coeff_T *coeffsp, char *linep, unsigned int numpoly )
{
double *q;
char *p;
double n;
coeffsp->numcoeffs = 0;
coeffsp->coeffs = NULL;
// strip comments...
if ( p = strchr( linep, '#' ) )
*p = '\0';
// get the tokens, ignoring spaces...
p = strtok( linep, " \t" );
while ( p )
{
// if there are no numeric values, exit loop.
if ( sscanf( p, "%lf", &n ) != 1 )
break;
// Increase the coefficiets list size.
if ( ! ( q = realloc( coeffsp->coeffs, sizeof (double) * (coeffsp->numcoeffs + 1) ) ) )
{
fprintf( stderr, "ERROR: Cannot allocate coefficients list (polynomial #%u).\n", numpoly );
exit(EXIT_FAILURE);
}
coeffsp->coeffs = q;
q[coeffsp->numcoeffs++] = n;
// get the next token.
p = strtok( NULL, " \t" );
}
// 0 means no coeficiets...
return coeffsp->numcoeffs;
}
Compiling, linking and running:
Code:
$ cc -o sys sys.c
$ ./sys test.txt
1: 1x^2 2x^1 3x^0
2: 3.14x^3 2.72x^2 10x^1 1x^0
3: 3x^3 2x^2 1x^1 4x^0