Search code examples
cloopsio

Iterating through rows in a file and comparing with the previous row


I would like to check if the first entry of the previous row is equivalent to the next row. Here is some of the data I am using:

Config,Prob,MAN,ATL,CVERT,TVERT,RIB,SCAP,PHUM,DHUM,PRAD,DRAD,CARP,PMC,DMC,PHX
LH,1,2,2,7,13,13,2,2,2,1,1,6,2,2,24
LH,1,0,0,0,0,9,1,2,2,2,2,12,2,2,18
LH,3,0,0,0,0,4,0,0,0,0,0,0,0,0,0
LH,1,0,0,0,13,24,2,2,2,2,2,12,2,2,24
LH,1,0,0,1,13,15,2,0,0,2,2,0,0,0,6
LH,1,0,0,0,0,10,0,1,1,0,0,0,0,0,18
LH,1,0,2,7,3,7,2,2,2,2,2,12,2,2,24
LH,1,0,0,2,0,14,1,2,2,2,2,0,0,0,18
LK,1,0,0,0,0,13,0,0,0,1,1,6,0,0,0
LK,1,2,2,7,13,17,1,0,0,0,0,0,0,0,6
LK,1,0,0,0,10,23,1,1,1,1,1,6,1,1,18
LK,1,2,2,7,0,18,2,0,0,1,1,12,2,2,24
LK,1,0,0,3,0,8,0,0,0,2,2,12,2,2,24
LK,1,2,2,7,0,8,0,0,0,2,2,12,2,2,24
LK,3,2,2,7,13,22,2,2,2,2,2,12,2,2,24
LK,1,2,2,7,0,2,0,0,0,0,0,0,0,0,0
LK,1,2,2,6,0,11,0,2,2,0,0,12,2,2,18

So in this case, I would like to count all the times the first entry of row changes. In this data, that would be equivalent to two (From Config to LH, then from LH to LK). Here is my attempted code:

int agents = 0;
int nrows = 0;
char buf[1024];
char *temp;
const char *tok;

while (fgets(buf, 1024, ifp)){
    tok = strtok(buf,",");
    if(nrows>0){
        if(strcmp(temp,tok) != 0){
            ++agents;
        }
    }

    temp = tok;
    nrows++;
}

My logic was that we want to skip the first iteration since temp doesn't contain anything, but will get assigned after the loop is finished. The next time the loop starts, we get the next row assigned to tok, compare with temp, which has the previous row. If they are different, increment, if not, continue. Assign temp to tok and repeat again. However, agents still returns 0 after looping through.

Therefore my logic is flawed, though I am not sure what part is. Any help is appreciated, thank you.


Solution

  • Store the first token of the first line ("Config" in your example), and compare it against the next line. When you find a change, replace the stored token. Use a counter to count the changes (how many times you replaced the stored token).

    You were close, but the way you think you are copying the token to the temporary is not correct. An easy fix would be to use a fixed-size array for that temporary, and when you want to copy, use strcpy().

    Full example:

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
        FILE* fp;
        const int sz = 256;
        char buffer[sz], tmp[sz] = {0};
    
        fp = fopen("file.txt", "r");
    
        int changes = 0;
        while(fgets(buffer, sz, (FILE*) fp))
        {
            // Eat trailining newline of fgets()
            if(buffer[strlen(buffer) - 1] == '\n')
                buffer[strlen(buffer) - 1] = '\0';
            const char* token = strtok(buffer, ",");
            if(strcmp(tmp, token) != 0)
            {
                strcpy(tmp, token);
                changes++;
            }
        }
        // changes - 1, because we always count the first line as a change
        printf("Changes = %d\n", --changes);
        fclose(fp);
        return 0;
    }
    

    Output:

    Changes = 2