这不是同一个逻辑吗?结果不同

时间:2014-07-23 22:15:21

标签: c file for-loop io while-loop

我不明白这两个代码是如何给我不同的结果的?

1

int main()
{

    struct stat buf1;
    struct stat buf2;

    FILE *fp1, *fp2;
    int ch1, ch2;
    clock_t elapsed;
    char fname1[40], fname2[40];

    printf("Enter name of first file:");
    fgets(fname1, 40, stdin);
    while (fname1[strlen(fname1) - 1] == '\n')
    {
        fname1[strlen(fname1) -1] = '\0';
    }

    printf("Enter name of second file:");
    fgets(fname2, 40, stdin);
    while (fname2[strlen(fname2) - 1] == '\n')
    {
        fname2[strlen(fname2) -1] = '\0';
    }

    fp1 = fopen(fname1, "r");
    if (fp1 == NULL)
    {
        printf("Cannot open %s for reading\n", fname1);
        exit(1);
    }

    fp2 = fopen(fname2, "r");
    if (fp2 == NULL)
    {
        printf("Cannot open %s for reading\n", fname2);
        exit(1);
    }

    stat(fname1, &buf1);
    size_t size1 = buf1.st_size;

    stat(fname2, &buf2);
    size_t size2 = buf2.st_size;

    printf("Size of file 1: %zd\n", size1);
    printf("Size of file 2: %zd\n", size2);

    elapsed = clock(); // get starting time

    size_t smallest = 0;

    if(size1 < size2)
    {
        smallest = size1;
    }
    else
    {
        smallest = size2;
    }

    int i;

    unsigned long long counter = 0;

    ch1 = getc(fp1);
    ch2 = getc(fp2);

    for(i = 0; i < smallest; i++)
    {       
        ch1 = getc(fp1);
        ch2 = getc(fp2);

        if((ch1 ^ ch2) == 0)
        {
            counter++;
        }
    }

    fclose (fp1); // close files
    fclose (fp2);

    float percent = (float)counter / (float)smallest * 100.0f ;

    printf("Counter: %u Total: %u\n", counter, smallest);
    printf("Percentage: %.2f%\n", percent);

    elapsed = clock() - elapsed; // elapsed time
    printf("That took %.2f seconds.\n", (float)elapsed/CLOCKS_PER_SEC);
    return 0;
}

2

... 


    ch1  =  getc(fp1); // read a value from each file
    ch2  =  getc(fp2);

    while(1) // keep reading while values are equal or not equal; only end if it reaches the end of one of the files
    {
        ch1 = getc(fp1);
        ch2 = getc(fp2);

        if((ch1 ^ ch2) == 0)
        {
            counter += 1;
        }

        total += 1;

        if ( ( ch1 == EOF) || ( ch2 == EOF)) // if either file reaches the end, then its over!
        {
            break; // if either value is EOF
        }
    }

    fclose (fp1); // close files
    fclose (fp2);

    float percent = (float)counter / (float)total * 100.0f ;

    printf("Counter: %u Total: %u\n", counter, total);
    printf("Percentage: %.2f%\n", percent);

    elapsed = clock() - elapsed; // elapsed time
    printf("That took %.4f seconds.\n", (float)elapsed/CLOCKS_PER_SEC);
    return 0;
}

第二个代码给了我更高的复制结果?它们不应该是一样的吗?只有一个更有效率。我通过添加并行性来运行Xeon Phi的第一个代码,但首先,我希望两个代码具有相同的重复率。

2 个答案:

答案 0 :(得分:1)

明显的区别在于, 2 在读取EOF时停止,而 1 则不会。实际上,2计算+1,然后在读取EOF时停止。在递增计数器之前,您应该进行EOF检查。

如果您更新 1 以检查EOF,您可能会发现相同的结果。

还不清楚为什么在每个循环开始之前从每个文件中读取和丢弃一个字符。

也许您忽略了st_size可能与可读字节数不对应,尤其是因为您将文件作为文本流打开。 (例如,在Windows中,st_size会将CR-LF计为两个,但getc只会获得\n)。

您可以尝试以二进制模式打开文件("rb")。另外,如果 2 (并报告哪个文件命中total),实际查看EOF的值可能会很有启发性。

答案 1 :(得分:0)

通过检查if((ch1 ^ ch2) == 0)您没有计算重复次数,您可以使用if(ch1 == ch2)代替