Ram said:
Hi all,
I have written the following code:
/* strtok example */
#include <stdio.h>
#include <string.h>
static const char * const resultFileName = "param.txt";
int main ()
{
FILE *fPtr;
char str[300];
char * pch;
int len;
char savedstr[300];
fPtr =fopen(resultFileName, "r");
if(fPtr == NULL)
{
printf("File doesnot exist");
return 1;
}
else
{
while(!feof(fPtr))
{
fgets(str,288,fPtr);
len = strlen(str);
str[len-1]=0;
for ( (pch=strtok(str,","));(pch = strtok(NULL,","));(pch
!=NULL))
{
strncpy(savedstr,pch,len);
printf("Saved String =%s\n",savedstr);
}
}
}
fclose(fPtr);
return 0;
}
I have a text file as the following:
param.txt:
"ram","lax","deepak"
10,20,30
40,80,100
70,90,100
and so on...
When I use strtok(delim ,) the problem is that the string "ram" never
gets stored in savedstr array while from "lax" onwards it gets stored.
1.Could any body suggest a better method so that I can store "ram"
also in the saved string and tokenize based on comma separated
delimiter?
The method you are using is not bad although I personally don't
like using fixed sizes like str[300], savedstr[300] when you are
storing into them data from a file. However, using these fixed
sizes makes the coding easier(IMO). The major problems in your
code is that you need to change the declaraion of savedstr to something
like char savedstr[MAXSTRINGS][MAXPARM+1] where the macros have
been appropriated defined. Also, you loop using feof is not
neccessary. You can loop with function fgets. fgets will return
NULL should the end of the file be encountered and there have
been no characters read into the character array.
To salvage your code make these changes mentioned:
/* strtok example */
#include <stdio.h>
#include <string.h>
#define MAXLINE 100
#define MAXSTRINGS 300
#define MAXPARM 30
static const char * const resultFileName = "param.txt";
int main (void)
{
FILE *fPtr;
char str[MAXLINE];
char * pch;
size_t i, count;
char savedstr[MAXSTRINGS][MAXPARM+1];
fPtr =fopen(resultFileName, "r");
if(fPtr == NULL)
{
printf("File doesnot exist");
return 1;
}
for(count = 0; (fgets(str,288,fPtr)) && count != MAXSTRINGS; )
for (pch=strtok(str,",");pch; pch = strtok(NULL,","))
{
strncpy(savedstr[count],pch,MAXPARM);
savedstr[count++][MAXPARM] = '\0';
}
fclose(fPtr);
for(i = 0 ;i < count;i++)
printf("savedstr[%u] = %s\n",i,savedstr
);
return 0;
}
2.Is there anything in C like (map in C++) so that I can store:
(key)
"ram"---->10,40,70(In an array of integer values)
"lax"---->20,80,90
Could anybody help me in this regard?
This makes the code a little more complicated. You should
probably create datatypes to store the data parsed from the file.
The actucal code depends on how the data is stored in the file.
In the following example, the contents in param.txt is:
"ram",10,20,30
"lax",40,80,100,500
"deepak",70,90,100,30,11
And the code(little tested) to parse the data in the file gives
the output:
Parm Name is "ram"
The values are: 10 20 30
Parm Name is "lax"
The values are: 40 80 100 500
Parm Name is "deepak"
The values are: 70 90 100 30 11
The code:
/* strtok example */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLINE 100
#define MAXPARM 30
typedef struct PARM
{
char parmname[MAXPARM+1];
int *parmvalue;
size_t valuecount;
} PARM;
typedef struct PARM_ARR
{
PARM *parm;
size_t parmcount;
} PARM_ARR;
PARM init;
int parseline(PARM_ARR *p, FILE *fp);
void freePARM_ARR(PARM_ARR *p);
void printPARM( PARM *p);
static const char * const resultFileName = "param.txt";
int main (void)
{
FILE *fPtr;
size_t i;
PARM_ARR my = {NULL};
fPtr =fopen(resultFileName, "r");
if(fPtr == NULL)
{
printf("File doesnot exist");
return 1;
}
while(parseline(&my,fPtr)) ;
fclose(fPtr);
for(i = 0; i < my.parmcount; i++)
printPARM(&my.parm);
freePARM_ARR(&my);
return 0;
}
int parseline(PARM_ARR *p, FILE *fp)
{ /* TODO: write more robust code to validate file data */
char *s,buf[MAXLINE];
size_t count;
PARM *tmp;
int *itmp;
while(1)
{ /* skip empty? line */
if(!fgets(buf,sizeof buf,fp)) return 0;
if(*buf != '\n') break;
}
tmp = realloc(p->parm,(p->parmcount+1)*(sizeof *tmp));
if(!tmp) return 0;
p->parm = tmp;
p->parm[p->parmcount] = init;
for(count = 0,s = strtok(buf,","); s ;
s = strtok(NULL,","), count++)
{
if(count == 0)
{
strncpy(p->parm[p->parmcount].parmname,s,MAXPARM);
p->parm[p->parmcount].parmname[MAXPARM] = '\0';
}
else
{
itmp = realloc(p->parm[p->parmcount].parmvalue,
(p->parm[p->parmcount].valuecount+1)*(sizeof *itmp));
if(!itmp) return 0;
p->parm[p->parmcount].parmvalue = itmp;
p->parm[p->parmcount].parmvalue[p->parm[p->parmcount].
valuecount++] =(int)strtol(s,NULL,10);
}
}
p->parmcount++;
return 1;
}
void freePARM_ARR(PARM_ARR *p)
{
size_t i;
for(i = 0;i < p->parmcount;i++)
free(p->parm.parmvalue);
free(p->parm);
p->parm = NULL;
p->parmcount = 0;
return;
}
void printPARM( PARM *p)
{
size_t i;
printf("Parm Name is %s\nThe values are: ", p->parmname);
for(i = 0;i < p->valuecount;i ++)
printf("%d ",p->parmvalue);
puts("\n");
return;
}