Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Proper error handling with strtok( ) ?

Status
Not open for further replies.

RealityVelJackson

Programmer
Aug 6, 2005
10
0
0
US
Suppose I am reading in the following text file, I would like to properly handle missing data between the #-delims when reading.

#mike#tyson#11898
#carl#lopez#98878
#vincent##11212
#utah#smith#

...

typedef struct{
char* field1;
char* field2;
int field3;
} CUSTOMER;

int main(){

char* s;
CUSTOMER* C = (CUSTOMER*) malloc (sizeof(CUSTOMER));
FILE* fp = fopen("customers.txt", "r");
if(fp == NULL){
fprintf(stderr, "file not found\n");
exit(1);
}

while(!feof(fp)){
s = (char*) calloc (255, sizeof(char));
fgets(s, 255, fp);

/* Add error checking code for missing fields...*/
C->field1 = strtok(s, "#");
C->field2 = strtok(NULL, "#");
C->field3 = atoi(strtok(NULL, "#"));

printStructMembers(C);
free(s);
}

free(C);
return 0;
}



 
1. Please use the [tt][ignore]
Code:
[/ignore][/tt]
tags when posting code.

2. CUSTOMER* C = (CUSTOMER*) malloc (sizeof(CUSTOMER));
There is no need to cast malloc in C. If you think you need to then either
a) make sure you've got [tt]#include <stdlib.h>[/tt]
b) you're using a C compiler and not a C++ compiler.

3. while(!feof(fp)){
feof() is a state, not a prediction. This kind of loop typically has the appearance of reading the last line 'twice'. This of course isn't really the case at all, but more a symptom of ignoring the return result of things like fgets().
Check my example below on how fgets() is normally used.

4. strtok() cannot handle multiple adjacent separators.
There is strsep(), but that's not an ANSI-C function, so you may not have it. Here is an example
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
   char* field1;
   char* field2;
   int field3;
} CUSTOMER;

void printStructMembers ( CUSTOMER* C ) {
  printf( "%s %s %d\n", C->field1, C->field2, C->field3 );
}
int main(){
   char s[256];
   CUSTOMER* C = malloc (sizeof(CUSTOMER));
   FILE* fp = fopen("customers.txt", "r");
   
   if(fp == NULL){
      fprintf(stderr, "file not found\n");
      exit(1);
   }

   while ( fgets(s, sizeof(s), fp) != NULL ) {
      char *p = s+1;  /* skip the leading # */
      /* still need to check for NULL being returned */
      C->field1 = strsep(&p, "#");
      C->field2 = strsep(&p, "#");
      C->field3 = atoi(strsep(&p, "#"));
      printStructMembers(C);
   }

   free(C);
   return 0;
}

$ ./a.out
mike tyson 11898
carl lopez 98878
vincent  11212
utah smith 0

--
 
That'll do it, I was not aware of the strsep() function.
In this case, suppose the data is coming straight from a DB table dump... I'm sure that 'many' programs have been written in C to parse this kind of information... Can you suggest a more elegant solution that performs the necessary error checking ? Thanks for the reply.

-Jason
 
If you need to do a lot of arbitrary string validation then you might do well to find a regular expression library of some kind.


Trojan.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top