Thread: Simple file parser

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    19

    Simple file parser

    Hi,
    I am writing a simple file parser for use in another project (for config file). The trickiest thing seems to be skipping unwanted characters (comments, spaces). It works partly, but after the second line of an inputed file processes only the first three characters.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    #define TEXT_FILE "data.txt"
    
    
    int check_char(char *str, int *pos);
    
    
    int main()
    {
        char buffer[1000];
        char buffer2[1000];
        int position = 0;
        int base = 0;
        FILE *file_ptr = fopen(TEXT_FILE, "r");
        if( file_ptr == NULL ) {
            perror(TEXT_FILE);
            exit(1);
        }
        
        memset(buffer, '\0', sizeof(buffer));
        memset(buffer2, '\0', sizeof(buffer2));
        
    
    
        while( fgets(buffer, sizeof(buffer), file_ptr) ) {
            base = 0;
            position = 0;
            printf("Data read: %s\n", buffer);
            while( check_char(&buffer[position], &position) ) {
                buffer2[base] = buffer[position];
                position++;
                base++;
            }
            buffer2[position] = 0;
            printf("Contents: %s\n", buffer2);
        
            memset(buffer, '\0', sizeof(buffer));
            memset(buffer2, '\0', sizeof(buffer2));
        }
        
        fclose(file_ptr);
        return 0;
    }
    
    
    int check_char(char *str, int *pos)
    {
        char ch = str[*pos];
        
        switch( ch ) {
            case '#':
                while( ch != '\n' )
                {
                    *pos = *pos + 1;
                    ch = str[*pos];
                    if( ch == '\0' || ch == EOF )
                        return 0;
                    printf("%c\n", str[*pos]);
                }
                return 1;
                break;
            case ' ':
                printf("Space\n");
                *pos = *pos + 1;
                return 1;
                break;
            case '\0':
            case EOF:
                printf("NULL or EOF\n");
                return 0;
                break;
            default:
                printf("OK\n");
                return 1;
        }
    }
    NOTE: Currently I am just trying to process and remove unwanted data, the actual processing of extracted data should be much simpler.

  2. #2
    Stoned Witch Barney McGrew's Avatar
    Join Date
    Oct 2012
    Location
    astaylea
    Posts
    420
    Maybe try something like this?:
    Code:
    #include <ctype.h>
    #include <stdio.h>
    
    int skip(FILE *iop)
    {
    	int c, incomment = 0;
    
    	do {
    		switch (c = getc(iop)) {
    		case EOF:
    			return EOF;
    		case '#':
    			incomment = 1;
    			break;
    		case '\n':
    			incomment = 0;
    			break;
    		}
    	} while (isspace(c) || incomment);
    	ungetc(c, iop);
    	return 0;
    }
    
    int main(void)
    {
    	char buf[10];
    
    	while (!skip(stdin) && scanf("%9[^\n\r\t #]", buf) == 1)
    		printf("\"%s\"\n", buf);
    }
    Last edited by Barney McGrew; 10-05-2013 at 05:21 AM.

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    This two lines have the same effect. You can see which is more elegant.

    Code:
    char buffer[1000] = { 0 };
        
    memset(buffer, '\0', sizeof(buffer));
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    Barney McGrew - thanks for the reply, I normally try to avoid using scanf but at least it works.

    std10093 - thanks, honestly didn't realise that. Does it initialise the whole buffer though?

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    19

    Lightbulb Solution:

    At last, found the solution. Line 25 of my code should instead read:

    Code:
    while( check_char(buffer, &position) ) {
    The function must have been unable to read the full range of the char array with the previous arguments.

  6. #6
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by Joshun View Post
    std10093 - thanks, honestly didn't realise that. Does it initialise the whole buffer though?
    Yes.

    You can check it with this:
    Code:
    #include <stdio.h>
      
    int main(void)
    {
        char buffer[1000] = { 0 };
        
        //memset(buffer, '\0', sizeof(buffer));
        
        int i;
        for(i = 0 ; i < 1000 ; ++i)
            if(buffer[i]!='\0')
                printf("not null\n");
      
        return 0;
         
    }
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    19
    I have now completed my parsing program / library (hopefully not too many bugs!), available at:
    https://github.com/Joshun/simple-parser

    With that finished, I can carry on with the game I was working on...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simple C Parser (-> XHTML)
    By SMurf in forum C Programming
    Replies: 6
    Last Post: 02-13-2013, 06:22 PM
  2. Simple parser - K&R ex6-2
    By lukasjob in forum C Programming
    Replies: 3
    Last Post: 11-16-2011, 08:46 AM
  3. simple question XML parser C
    By RoxPro in forum C Programming
    Replies: 19
    Last Post: 08-22-2011, 01:57 AM
  4. Simple parser
    By lruc in forum C Programming
    Replies: 5
    Last Post: 11-19-2009, 12:19 AM
  5. Simple Parser Program
    By ChJees in forum C++ Programming
    Replies: 4
    Last Post: 07-19-2007, 03:21 AM

Tags for this Thread