Thread: Putting strings into an array from a text file.

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

    Putting strings into an array from a text file.

    Hi All,

    I have a text file with the following information:
    Bloggs,Joe,26-07-82

    I want to split this information into different fields, which will be stored in an array.

    My first problem is how do I split up the information into seperate fields, such as FirstName, SurName, DOB. I need some method of reading the text untill it gets to the first comma. And then the same again for the second comma etc.

    My second problem is how to get the program to read the information on from a text file, perform the string sepperation, described above and put this information into an array.

    I have basic knowledge of C but have a firm understanding of the basic concepts.

    I have been told that the STRUCT method may be of use. Also the STROK / TOKEN method may be useful for seperating the string.

    I would be very gratefull for any help!!!

    Cheers
    John

  2. #2
    .
    Join Date
    Nov 2003
    Posts
    307
    This is a csv handler routine, you modify the struct and the FLDS define, plus the char *fmt line if you have different numbers of flds
    Code:
    /* sample.c from code snippets we use for the exact same purpose sorting 
                tab-delimited files qsort() is generally more efficient */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define DELIMITER ","                          /* token separator */
    #define ARR_SIZE 2500                          /* largest possible number of records */
    #define BUFSZ 256                              /* char in read buffer */
    
    #define FLDS 3                                 /* fields in struct */
    
    typedef struct {
           char lnm[25];
           char first[20];
           char date[12];
    } rec;
    void check(int);           
    int comp(void *, void *);
    void parse(char *, rec *,int *);
    void tst(FILE *);
    void createoffsets(int *,rec *);
    void printit(rec *,int);
    
    int main(int argc, char *argv[]){
    	FILE *in=NULL;
    	char tmp[BUFSZ]={'\0'};
    	rec records[ARR_SIZE];
    	rec *ptr=records;
    	int count=0;
    	int offset[7]={0};
    	tst(in=fopen(argv[1],"r"));	
    	createoffsets(offset,ptr);
    	while(!feof(in)){
    	     memset(tmp,0x00,sizeof(tmp));
    	     if(fgets(tmp,BUFSZ-1,in)!=NULL){
    	      	  parse(tmp,ptr++,offset);
    	      	  check(count++);
    	     } 	  
    	}
    	if(fclose(in)==EOF){
    		perror("Error on input file");
    		exit(EXIT_FAILURE);
    	}
    	qsort(records,count,sizeof(records[0]),comp);
    	printf("records found:%d\n",count);
    	printit(records,count);
    	return 0;
    }
    void tst(FILE *test){                                   /* check on file open */
    	if (test==NULL){
    	    perror("Error opening file");
    	    exit(EXIT_FAILURE);
    	}
    }
    void parse(char *tmp, rec *recptr, int *offset){       /* whack string into struct fields */
    	  char *fmt[FLDS+1]={"%24s","%19s","%11s",""};
    	  int i=0,   *local=offset;
              char *buf, **fmtptr=fmt;
              buf=strstr(tmp,"\n");
              if(buf)*buf=0x00;
              memset(recptr,0x00,sizeof(rec));
              for(buf=strtok(tmp,DELIMITER); 
                  buf!=NULL;
                  buf=strtok(NULL,DELIMITER),local++,fmtptr++){
                       sprintf(recptr->city + *local,*fmtptr,buf);                  
              }
    }
    void printit(rec *recs, int count){                /* dump array of structs */
    	  rec *local;
    	  int i=1;
              printf("%d records found, sorted by population size:\n",count);
              for(local=recs;count;count--,local++)	
                 printf("%22s %2s %8s\n",                   
                        local->city,
                        local->state,
                        local->population);
    }
    int comp(void *c, void *d){                          /* function for qsort */
    	rec *a, *b;
    	a=(rec *)c;
    	b=(rec *)d;
    	return strcmp(a->lnm,b->lnm );
    }
    void createoffsets(int *values, rec *recptr){       /* create pointer offsets for struct */
         char *base=recptr->lnm;     
         char *buf=recptr->first;	
         *values++=0;     
         *values++=(int)buf - (int)base;
         buf=recptr->date;
         *values++=(int)buf - (int)base;
    }
    void check(int count){                              /* check array bounds */
         if( ARR_SIZE +1 == count){                     /* change this to whatever you need */
                printf("Maximum possible number of records read in, aborting\n");
                exit(EXIT_FAILURE);                     /* puke before we core dump */
         }	
    }

  3. #3
    Registered User
    Join Date
    Nov 2003
    Posts
    9
    Hi, thanks for the code, I understand some of it
    Is there any chance you could give me a very basic example so I can build on that myself?

    Cheers
    John

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Here's a very basic (and somewhat inefficient) parser.

    Code:
    int
     get_substring(char dest[], const char src[], int * index, char sep)
    {
     int i = 0;
     
        while(src[*index] != sep && src[*index] != 0)
       {
        dest[i++] = src[(*index)++];
       }
       
      dest[i] = 0;
      
      /* are we done? */
      if(src[*index] == 0) return *index = 0; 
      
     /* otherwise, advance to the next index */
     return ++(*index);
    }


    Note that if the function encounters more than one separator in a row, it just returns normally but fills the first element of "dest" with null, ie:



    Code:
    int main()
    {
     char buff[100];
     
     char str[] = "One...two. Three.";
     
     int next = 0; 
     
        while( get_substring(buff, str, &next, '.') )
       {
           if(buff[0] != 0) printf("%s\n", buff);
       }
    
     return 0;
    }

    In reality, you wouldn't want that inefficiency, but the idea here is to demonstrate an easy-to-understand mechanism...
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Casual Visitor
    Join Date
    Oct 2001
    Posts
    350
    A very basic approach to the first part using strtok.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
      char buf[BUFSIZ], line[] = "Bloggs,Joe,26-07-82", *p;
    
      p = strtok(line, ",");
    
      while(p != NULL)
      {
         strcat(buf, p);
         strcat(buf, "\n");
         p = strtok(NULL, ",");
      }
    
      puts(buf);
      while(getchar() != '\n');
    
      return 0;
    }
    Reading from the file *should* have a similar process. Read a line from the file into a buffer, test for your comma, if you have data to copy, use strcpy to place it into your struct array.
    I haven't used a compiler in ages, so please be gentle as I try to reacclimate myself. :P

  6. #6
    Registered User
    Join Date
    Nov 2003
    Posts
    9
    Hi everyone,
    Thanks for your help so far!

    However, I need a little more help.

    Here is my program so far:

    Code:
    #include <string.h>
    #include <stdio.h>
    
    char seps[]   = " ,";
    char *token;
    char Fname[10];
    char Lname[10];
    char Reg[10];
    char Dob[10];
    
    void main()
    {
    	char s[100];
    	FILE * f;
    	int len, i;
    	i=0;
    	f = fopen("c:\\students.txt","r");
    
    		for ( ; ; ) {
    			fgets(s, 100, f);
    			if feof(f) break;
    			len = strlen(s);
    			if (len) { s[len] = 0; }
       token = strtok( s, seps );
       while( token != NULL )
       {
    	   
    	   i++;
    	   /* While there are tokens in "string" */
          printf( " %s", token );
    
    	  /* Get next token: */
          token = strtok( NULL, seps );
       }
    
    		}
    		fclose(f);
    
    }
    This program sucessfully reads in the information from my txt file and seperates the data using the comma's in the text.
    The problem is, I want to put each data field (beginning with Surname, First Name, RegNo, DOB) into reserved arrays. Within a structure would be nice, so that I can view the data, student by student.
    I have included a i++ incrementer but dont know if that would be of any use.

    Please help, I have been wercking my brain trying to solve this one.

    cheers
    John

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  2. Reading in an array of text from a file?
    By suzakugaiden in forum C++ Programming
    Replies: 6
    Last Post: 01-04-2006, 03:17 PM
  3. what does this mean to you?
    By pkananen in forum C++ Programming
    Replies: 8
    Last Post: 02-04-2002, 03:58 PM
  4. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM