C语言,文件定位问题详解

最近在完成上机题碰到文件操作,要求能够修改某一行的数据,关于这个问题,我们自然就会想到用fseek来定位然后修改这一行的内容,可是问题就来了,具体啥问题请往下看。

比如说text.txt的内容为
C语言,文件定位问题详解_第1张图片
这时我想把第二内容改为24
很明显用fseek定位到第二行然后直接改就行了,代码如下:

#include
#include
#include
#include
using namespace std;
#define N 1000
int len;
char buf[N];
char buf1[N];
int main()
{
    FILE* fp; int i, i1;

    i = 2;
    i1 = i;
    errno_t err;
    if ((err = fopen_s(&fp,"text.txt", "r+")) != NULL) { cout << "The file can not be opened.\n"; exit(0); }
for (; i1 >= 1; i1--)
        fgets(buf1, N, fp);
    fseek(fp, 0L, SEEK_CUR);
    strcpy_s(buf1,"24");
    rewind(fp);
    for (; i>1; --i)
        fgets(buf, N, fp);
    fseek(fp, 0, SEEK_CUR);
    fputs(buf1,fp);
    return 0;
}

这段代码没啥好解释的,就是简单的定位到第二行,然后修改,可是结果却很神奇,
C语言,文件定位问题详解_第2张图片
那么问题来了,为什么会出现这种情况,3不是应该在第三行吗为什么跑上面了,当时我是一脸懵逼,不过既然出现问题了,我们就好好分析,不能轻言放弃,这是作为程序猿的基本素养对不对。

小小的尝试:加换行符

ok很明显问题是少了一个换行符,那么我们在最后一个字符后面加个换行符看行不行,即将上面的代码改一下:

strcpy_s(buf1,"24\n");

然而更神奇的现象出现了,
C语言,文件定位问题详解_第3张图片
怎么回事,为什么下面的3不见了?
好了,到这里,你肯定怀疑人生了,当然解决办法不是没有,有种思路是把第二后面数据全部保存起来,改完第二行,再覆盖进去,在这里我就不演示了。下面我们来仔细分析一下为什么会出现这个现象。

问题本源:

其实结合上面的例子我们应该已经看出点猫腻了,其实有一点很重要:一旦文件被你输进去,其字符串所占的大小就固定了。

这是我经过大量的例子发现的,这点很重要,知道了这个,上面的现象就可以解释了。
在第一个例子中,我们的文件里面是:
1
2
3
4
我把这些转换成字符形式方便看:‘1’,‘\n’ ,’2’, ‘\n’, ‘3’, ‘\n’ ,’4’
ok那么当我们吧第二行改成’2’ ‘4’时,’4’自然把’2’后面的换行符给占掉了,所以’3’跑上面去了,第二例子用同样的思路也能分析出来,我就不做赘述了。

解决方案:

既然知道了问题的本源,那么解决方法就很明了了,既然我们一旦输入大小就固定了,那么我们在输入的时候在每一行输完的时候不要先急着换行多输入几个空格,保证修改的数据不会超过加上空格后的长度,即:
C语言,文件定位问题详解_第4张图片
就像这样,那么我试验一下
C语言,文件定位问题详解_第5张图片
第一次一点没改的代码就成功了。

你可能感兴趣的:(c)