C 迭代文件中的行并与前一行进行比较

C 迭代文件中的行并与前一行进行比较,c,loops,io,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

我想检查前一行的第一个条目是否等同于下一行。以下是我正在使用的一些数据:

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
所以在本例中,我想计算行的第一个条目发生更改的所有时间。在这个数据中,这相当于两个(从配置到左侧,然后从左侧到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
并再次重复。但是,
代理在循环通过后仍然返回0


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

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

您很接近,但您认为将令牌复制到临时令牌的方式是不正确的。一个简单的解决方法是使用固定大小的数组进行临时复制,当您想要复制时,使用

完整示例:

#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;
}
#包括
#包括
内部主(空)
{
文件*fp;
常数int sz=256;
字符缓冲区[sz],tmp[sz]={0};
fp=fopen(“file.txt”,“r”);
int变化=0;
while(fgets(缓冲区,sz,(文件*)fp))
{
//fgets的新行()
if(buffer[strlen(buffer)-1]=='\n')
缓冲区[strlen(buffer)-1]='\0';
const char*token=strtok(缓冲区,“,”);
如果(strcmp(tmp,令牌)!=0)
{
strcpy(tmp,令牌);
变化++;
}
}
//更改-1,因为我们总是将第一行计算为更改
printf(“更改=%d\n”,--Changes);
fclose(fp);
返回0;
}
输出:

变化=2


您还可以使用
fscanf()
functions系列,代码更简单、更短!:

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

简单的赋值
temp=tok
是无用的……它只是复制缓冲区的地址。您真正想要的是为temp和strcpy()分配一些内存。
n = 2
Process finished with exit code 0