fgetc 没有停止我的循环

fgetc is not stopping my loop

int ch;
char Name1[24], Name2[24],*p1,*p2;  
while ((ch = fgetc(inz)) != EOF){

            fseek(inz, -1, SEEK_CUR);

        fgets(Name1, 24, inz);
        fgets(Name2, 24, inz);
        p1 = Name1;
        p2 = Name2;
        p1 += 3;
        p2 += 3;

        if (atoi(p1) > atoi(p2)){
            fseek(inz, -46, SEEK_CUR);              
            fputs(Name2, inz);              
            fputs(Name1, inz);              

        }
        fseek(inz, -23, SEEK_CUR);      
        i --;
    }

我有这个代码。 inz 是我在 r+ mod 中的文件。我想将每个字符串与下一个字符串进行比较,并根据第 4 个字符对它们进行排序。该功能正在运行,但是......它永远运行不可阻挡...... **我试图改变 int ch;炭也。还是不行,feof也不行

你的代码有几个问题:

1) 您假设每行至少有 4 个字符长(加上换行符)。如果该行小于 4 个字节,您将不会根据字符串本身进行排序,而可能会根据未初始化的内存进行排序。

2) 你说你要根据第4个字符比较每行,但你实际上是根据从第4个字符开始的字符串进行比较。您正在将它转换为整数,这意味着您还假设该行包含一个数值。

3) 您假设每个字符串在文件中占用 24 个字节。我猜你假设每个字符串都是 23 个字符长加上一个换行符?这个假设有效吗?如果行可以短于 24 个字节,则此代码不正确:

fseek(inz, -46, SEEK_CUR);              

相反,您想倒回两个字符串的实际总长度加上两个换行符。即使字符串是 23 个字节,您也不会在此处考虑换行符,因此您希望倒带 -48 而不是 -46。

4) 将字符串写回文件时,您使用的是不包含换行符的 fputs。

5) 您并没有真正对文件进行排序,您只是在进行一次冒泡排序迭代。您正在根据比较对当前两行进行重新排序,但这不会对整个文件进行排序。所以排序的逻辑也是错误的。

读取每一行,将其粘贴到数组中,根据您提到的条件对数组进行排序,然后将其写回文件会更清晰。

除此之外,为什么循环永远不会结束?

循环中的最后一行是这样的:

fseek(inz, -23, SEEK_CUR);  

这意味着它总是在尝试获取下一个字符 (fgetc) 之前返回 23 个字节。那时你将永远看不到 EOF。

好吧,如果您执行 fgets 并且文件指针已经位于文件末尾,您将只会得到一个 EOF。在您测试 return 值的唯一 fgetc 之前的指令是 fseek(inz, -23, SEEK_CUR);.

这意味着当您到达文件末尾时,您首先返回 23 个字节,成功读取某些内容,并且可能在以下两个 fgets 中的任何一个上获得 EOF,其中 returned 值被忽略。并永远重复...

你应该怎么办?至少测试每个读取函数的 return 值:

    if (fgets(Name1, 24, inz) == NULL) break;
    if (fgets(Name2, 24, inz) == NULL) break;

但这还不是全部。除非你真的确定你所有的行总是正好有 23 个字符并且文件以二进制模式打开(或者你在 Linux)永远不要使用这样的 fseek.唯一合理的方法是用 ftell 存储一个位置,然后 fseek 到那个位置。

最后但并非最不重要的一点是,您的算法返回一行以在 Name1 中读取您刚刚在 Name2 中读取的内容。您应该交换 p1 和 p2,始终读入 p2 并比较 p1 和 p2

无论行大小如何,只要它们都小于 SIZE 但大于 4,这个文件就会对文件进行排序:

size_t oldpos = 0, tmp;
char Name1[SIZE], Name2[SIZE],*p1,*p2;
p1 = Name1;
p2 = Name2;
/* read first line and note position after it */
if (fgets(p1, SIZE, inz) == NULL) return;
tmp = ftell(inz);
/* loop reading in p2 */
while (fgets(p2, SIZE, inz) != NULL){

    if (atoi(p1 + 3) > atoi(p2 + 3)){
        /* swap last two lines */
        fseek(inz, oldpos, SEEK_SET);              
        fputs(p2, inz);
        fputs(p1, inz);          
        /* and go back to beginning of file - not optimal but robust */    
        fseek(inz, 0, SEEK_SET);
        /* again last line in p1 and note position */
        fgets(p1, SIZE, inz);
        oldpos = 0;
        tmp = ftell(inz);
    }
    else {
        /* order is ok untill here, note new position and swap buffers */
        oldpos = tmp;
        tmp = ftell(inz);
        swap(&p1, &p2);
    }
}