Thread: reading from a file

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    3

    reading from a file

    Hi,

    This is the first part of a program I'm writing. At the moment I'm trying to read from a file and print on the screen, the data shown below (in the format shown), using a linked list. I have managed to get it to work if just column_1 and column_2 are present in the dat file (see program below) but cant figure out how to add to my program to get it to read the whole lot.

    Hope that makes sense!

    Any help or advice would be greatly appreciated
    Thanks a lot.

    jamestunic

    ---------------------------------------
    value_1: 10.334
    value_2: 25.998
    column_1 column_2
    0 0
    5.623 10.876
    10.484 14.988
    13.983 18.765
    17.342 25.922
    20.154 27.245
    23.998 29.284
    26.655 32.523
    29.762 35.924
    ---------------------------------------

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
    char line[101], filename_read[101];
    char *line_ptr;
    
    struct node
    	{
    	double column_1, column_2;
    	struct node *next;
    	};
    struct node *first_ptr, *new_ptr, *previous_ptr, *current_ptr;
    int no_nodes = 0, no_values = 2;
    FILE *input_stream;
    
    fprintf(stdout, "Enter the name of the file to read data from:");
    fscanf(stdin, "%s", filename_read);
    first_ptr = NULL;
    
    if ((input_stream = fopen(filename_read, "r")) !=NULL)
    	{
    	line_ptr = fgets(line, sizeof(line), input_stream);
    	while((no_values == 2) && ((line_ptr = fgets(line, sizeof(line), input_stream)) != NULL)) 
    		{
    		new_ptr = (struct node *)malloc(sizeof(struct node));
    		if(first_ptr != NULL)	 
    			previous_ptr->next = new_ptr;
    		else
    			first_ptr = new_ptr;
    		new_ptr->next = NULL;
    		no_values = sscanf(line, "%lf %lf",
    						   &new_ptr->column_1,
    						   &new_ptr->column_2);
    						   previous_ptr = new_ptr;				
    		}
        if((first_ptr != NULL) && (no_values == 2))
    		{
    		current_ptr = first_ptr;
    		while(current_ptr->next != NULL)
    			{
    			fprintf(stdout, "%lf\t %lf\n", current_ptr->column_1, current_ptr->column_2);
    			current_ptr = current_ptr->next;
    			}
    			fprintf(stdout, "%lf\t %lf\n", current_ptr->column_1, current_ptr->column_2);
    		}
    	
    	if((line_ptr != NULL) && (no_values != 2))
    		fprintf(stdout, "Error reading line %s\n", line);
    	else
    		if(line_ptr == NULL)
    			fprintf(stdout, "End of file found\n");
    	}
    return(0);
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    What's the matter, haven't you heard about functions?
    Once again you've overly complicated things by compressing the entire program into main.
    The wacky formatting no doubt adds to the confusion. It seems that you're using a mix of spaces and tabs in your editor. If you want the code to look the same here (and in everyone elses editors), then use spaces only.

    I hope you can see from this how much clearer the whole thing is, because it uses functions to implement clearly defined sub-tasks.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct node {
        double column1, column2;
        struct node *next;
    };
    typedef struct node node_t;
    
    /* appends a new node to an existing (possibly empty) list */
    node_t *append ( node_t *head, double col1, double col2 ) {
        node_t  *new = malloc( sizeof *new );   /* allocate a new node */
    
        if ( new == NULL ) {                    /* check */
            perror( "Can't allocate" );
            return head;                        /* return current list on error */
        }
    
        new->column1 = col1;
        new->column2 = col2;
        new->next = NULL;                       /* fill in the data */
    
        if ( head == NULL ) {
            head = new;                         /* empty list, new node is the head */
        } else {
            node_t  *temp = head;               /* find the end and append */
            while ( temp->next != NULL ) temp = temp->next;
            temp->next = new;
        }
        return head;
    }
    
    /* run through the list, printing each node */
    void print ( node_t *head ) {
        while ( head != NULL ) {
            printf( "Col1=%f, Col2=%f\n", head->column1, head->column2 );
            head = head->next;
        }
    }
    
    /* reads a file, and appends nodes to a list. */
    node_t *read_file ( FILE *fp ) {
        char    buff[BUFSIZ];
        node_t  *list = NULL;
        while ( fgets( buff, sizeof buff, fp ) != NULL ) {
            double col1, col2;
            if ( sscanf( buff, "%lf %lf", &col1, &col2 ) == 2 ) {
                list = append( list, col1, col2 );
            } else {
                fprintf( stderr, "Bad line %s", buff );
            }
        }
        return list;
    }
    
    int main ( void ) {
        char    filename[BUFSIZ];
        char    *nl;
        node_t  *list = NULL;
        FILE    *input_stream;
    
        fprintf(stdout, "Enter the name of the file to read data from:");
        fflush(stdout);
        fgets(filename, sizeof filename, stdin );
        nl = strchr(filename,'\n');
        if ( nl != NULL ) *nl = '\0';
    
        input_stream = fopen( filename, "r" );
        if ( input_stream == NULL ) {
            perror( "Unable to open file" );
        } else {
            list = read_file ( input_stream );
            print( list );
            fclose( input_stream );
        }
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2003
    Posts
    3
    Thank you very much for your quick reply. I see what you mean about splitting the program up to make it clearer.

    I'm very new to C programming (which is obvious ) and havent yet come across a lot of the functions that you've used in your program. Although I appreciate you writing the new code for me is there a way I could add to my existing code to get it to read the first two lines in the dat file as well as the two columns!?

    Again any help would be greatly appreciated!

    jamestunic

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. opening empty file causes access violation
    By trevordunstan in forum C Programming
    Replies: 10
    Last Post: 10-21-2008, 11:19 PM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM