Need help in File Parsing in C/C++ !!

Hi All,

I have to write a C/C++ code which can read a text file with the following contents :

Device ID no of ALIVE No of SEARCH no of BYEBYE
uuid:22314754-a597-490b-8a93-02cfae01036b ALIVE 16
uuid:22314754-a597-490b-8a93-02cfae01036b SEARCH 8
uuid:2ad9982a-c1ee-4037-8029-90b00c89a368 ALIVE 13
uuid:50e65653-7525-485d-83bf-d293558c4264 ALIVE 32
uuid:50e65653-7525-485d-83bf-d293558c4264 BYEBYE 8
uuid:55076f6e-6b79-4d65-6497-180373763bc1 ALIVE 113
uuid:55076f6e-6b79-4d65-6497-180373763bc1 SEARCH 111
uuid:55076f6e-6b79-4d65-6497-180373763bc1 BYEBYE 112


And format it such that the output file will be printed like below :

Device ID no of ALIVE No of SEARCH no of BYEBYE
uuid:22314754-a597-490b-8a93-02cfae01036b 16 8 0
uuid:2ad9982a-c1ee-4037-8029-90b00c89a368 13 0 0
uuid:50e65653-7525-485d-83bf-d293558c4264 32 0 8
uuid:55076f6e-6b79-4d65-6497-180373763bc1 113 111 112

The above is just an example ,basically the Device id will be getting populated dynamically, so each time,the "uuid:" string name and their occurrences(ALIVE/SEARCH/BYEBYE) might be different,so how to format it in such a way that I can track reading from any input file (with different uuid string name and different occurences) and print to an output file format,Any ideas?

Regards
Debasis

Last edited on
Your input has three values per line: id, type, count. There are three types.

You could have a struct "Counts" that holds alive, search, and byebye. Then you would create a map<string,Counts>.

For every line of input:
* If map has key 'id', then update appropriate field of its Counts
* If map does not have key yet, then add entry (id,Counts), where Counts has appropriate field set

Output is simple: for each key in map, print key (i.e. the id) and all three fields of the Counts value.
Hi,

This is could be one of the solution for the problem above.
This is easily achievable using standard template library
you declare four string variable mainly for device id,alive,search and byebye.
Read file line by line and tokenize and store in a vector.


if 2nd element is ALIVE store device id and value of ALIVE.
read next line ,store in vector and look for SEARCH ,store value of SEARCH
and so on.
Hope this will be a step insolving this problem




Thanks for the answer.

I got to check.Can we create a map for a dynamic text file ,which is getting populated continuously, with different uuid values ?
Yes. Consider:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Counts {
  int x;
  int y;
  Counts( int a, int b ) : x(a), y(b) {}
};

map<string,Counts> data;

string uuid = ...
int myX = ...
auto it = data.find( uuid );
if ( data.end() != it )
{
  it->second.x = myX;
}
else
{
  data.emplace( make_pair( uuid, Counts(myX,0) );
}
The requirement is to capture statistics of uuid occurrences for ALIVE/SEARCH/BYEBYE (it can be all 3, combinations of 2 each, or one alone) in a dynamically populated file in run time.

I am able to print all 3 combinations, but not in combination of 1 or 2 e.g.

If my input.txt is like this :
uuid:22314754-a597-490b-8a93-02cfae01036b ALIVE 16
uuid:22314754-a597-490b-8a93-02cfae01036b BYEBYE 8
uuid:22314754-a597-490b-8a93-02cfae01036b SEARCH 8
uuid:50e65653-7525-485d-83bf-d293558c4264 ALIVE 32
uuid:50e65653-7525-485d-83bf-d293558c4264 BYEBYE 8
uuid:50e65653-7525-485d-83bf-d293558c4264 SEARCH 132
uuid:55076f6e-6b79-4d65-6497-180373763bc1 ALIVE 113
uuid:55076f6e-6b79-4d65-6497-180373763bc1 BYEBYE 112
uuid:55076f6e-6b79-4d65-6497-180373763bc1 SEARCH 111
uuid:T0100203354 ALIVE 1
uuid:T0100203354 BYEBYE 2
uuid:T0100203354 SEARCH 3

My code :

#include<stdio.h>
#include<string.h>
struct uid
{

char uid_val[100];
char state[100];
int temp_count;
int alive_count;
int search_count;
int bye_count;

}UID[100];



int main()
{

char str[100];
int i = 0;

int line = 0;

char temp_val[100] = "waseem";

FILE *fp1 = fopen("input.txt","r");
FILE *fp2=fopen("output.txt","w");


printf("init value is %s \n",temp_val);
while(!feof(fp1))
{

        fscanf(fp1,"%s %s %d",UID[i].uid_val,UID[i].state,&UID[i].temp_count);

        int ret = 0;
        ret=strcmp(UID[i].uid_val,temp_val);
        if (ret!=0)

        {
               printf("new UID_val is %s\n",UID[i].uid_val);
//              i++;
        }
        else
        {

        }

        temp_val[0] = '\0';

        strcpy(temp_val,UID[i].uid_val);
//      printf("value is %s and %s and ret is %d\n",temp_val,UID[i].uid_val,ret);

        if(strcmp(UID[i].state,"ALIVE")==0)
        {
                UID[i].alive_count = UID[i].temp_count;
        }
        else if(strcmp(UID[i].state,"BYEBYE")==0)
        {
                UID[i].search_count = UID[i].temp_count;
        }
        else
        {
                UID[i].bye_count = UID[i].temp_count;
        }

        //printf("UID is %s  State is %s  Count is %d\n",UID[i].uid_val,UID[i].state,UID[i].alive_count);
        line++;

        if(line%3 == 0)
        {
                i++;
        }
}

//printf("value of is %d and lines is %d\n",i,line);
int n = 0;
//fp2=fopen("output.txt","w");

if (fp2==NULL)
  {
printf("cant output to file\n");
}
else

{
fprintf(fp2,"Device ID\t\t\t\t\tALIVE\tBYEBYE\tSEARCH\n");
  for(n = 0;n < i;n++)
        {
fprintf(fp2,"%s\t%d\t%d\t%d\n",UID[n].uid_val,UID[n].alive_count,UID[n].search_count,UID[n].bye_count);
}


}

//      for(n = 0;n < i;n++)
        {
//              printf("%s    %d %d  %d\n",UID[n].uid_val,UID[n].alive_count,UID[n].search_count,UID[n].bye_count);

//      }

        fclose(fp1);
        fclose (fp2);

        return 0;
}}



Gives the following output :(output.txt)

Device ID ALIVE BYEBYE SEARCH
uuid:22314754-a597-490b-8a93-02cfae01036b 16 8 8
uuid:50e65653-7525-485d-83bf-d293558c4264 32 8 132
uuid:55076f6e-6b79-4d65-6497-180373763bc1 113 112 111
uuid:T0100203354 1 2 3

I want to generalize the code such that uuid occurrence does not have to be all 3 (ALIVE/SEARCH/BYEBYE), the occurrences can be any combination and code should work. e.g my code gives wrong results when input.txt contains the following:

uuid:22314754-a597-490b-8a93-02cfae01036b BYEBYE 8
uuid:22314754-a597-490b-8a93-02cfae01036b SEARCH 8
uuid:50e65653-7525-485d-83bf-d293558c4264 ALIVE 32
uuid:50e65653-7525-485d-83bf-d293558c4264 BYEBYE 8
uuid:55076f6e-6b79-4d65-6497-180373763bc1 ALIVE 113
uuid:55076f6e-6b79-4d65-6497-180373763bc1 BYEBYE 112
uuid:55076f6e-6b79-4d65-6497-180373763bc1 SEARCH 111
uuid:T0100203354 BYEBYE 2

I am using ubuntu for gcc/g+ compiler.
Last edited on
You are using C. C++ has much more "convenience features".

You do assume that each set of three lines has same uuid. Don't.

Do not read into UID[i]. Read everything into temporary object. Then you don't need the temp_count and state in the struct.

When you have a new line in memory, you have two possibilities:

1. Same uuid is already in list. If so, update that element in the list. You obviously have to search the list by the uuid field every time you do read a line.

2. New uuid. Now, and only now, you do add a new element to the list. Remember to initialize the other two counters to 0.
Topic archived. No new replies allowed.