遍历文件中的行并与上一行进行比较

时间:2019-07-10 18:23:49

标签: c loops io

我想检查上一行的第一项是否等效于下一行。这是我正在使用的一些数据:

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

因此,在这种情况下,我想计算行的第一项更改的所有次数。在此数据中,这相当于两个(从Config到LH,然后从LH到LK)。这是我尝试的代码:

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++;
}

我的逻辑是我们想跳过第一次迭代,因为temp不包含任何内容,但是将在循环完成后进行分配。下一次循环开始时,我们将获得分配给tok的下一行,并与具有上一行的temp进行比较。如果它们不同,则增加,否则,继续。将temp分配给tok,然后再次重复。但是,agents循环后仍返回0。

因此,尽管我不确定是哪一部分,但我的逻辑还是有缺陷的。感谢您的任何帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

存储第一行的第一个标记(在您的示例中为“ Config”),并将其与下一行进行比较。找到更改后,请替换存储的令牌。使用计数器来计数更改(更换存储令牌的次数)。

您已经接近,但是您认为将令牌复制到临时文件的方式不正确。一个简单的解决方法是对该临时文件使用固定大小的数组,然后在要复制时使用strcpy()

完整示例:

#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;
}

输出:

  

更改= 2

答案 1 :(得分:0)

您还可以使用fscanf()函数家族,代码更加简单和短促! :

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(){
    FILE* file = fopen("data.txt", "r");
    char token[256];
    char tmp[256];
    int  read = -1;
    int  n    = 0;

    while (1){
        read = fscanf(file, "%[^,]", token);
        fscanf(file, "%*[^\n]\n");/*go to next line*/
        if(read != 1)
            break;
        if(strcmp(token, tmp) != 0){
            ++n;
            strcpy(tmp, token);
        }
    }
    fclose(file);
    printf("n = %d\n", --n);
    return 0;
}

输出:

n = 2
Process finished with exit code 0