免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2270 | 回复: 2
打印 上一主题 下一主题

[C] 对C语言同时读写不理解,求大神解答 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-24 21:40 |只看该作者 |倒序浏览
本帖最后由 huangzhenfan 于 2012-08-25 00:05 编辑

源码如下:


#include <stdio.h>
struct record
{
   char a;
};
int main(void)
{
    FILE *fp;
    struct record rec;
    fp = fopen("testfile.txt", "r+");
    if (fp != NULL)
    {
      while (fread((char *)&rec, sizeof(rec), 1, fp)==1)
      { /* 对rec执行某些操作 */
        ++rec.a;
        if (1/* rec 须被重新写入 */)
        {
         fseek(fp, -(long)sizeof(rec), 1); /* SEEK_CUR */
         fwrite((char *)&rec, sizeof(rec), 1, fp);
         fflush(fp); /* 必须要加上这句,或者 fseek(fp, 0, 1); 写操作才能成功 */
        }

    }
   fclose(fp);
   return 0;
}

为什么使用fflush(fp),或fseek(fp,0,1)后才能解决死循环,求分析。




我在gcc4.45 和vc2010上测试。得出读写是使用同一个offset的

测试代码如下:

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

int main (void)
{
     FILE *fp;

    //  缓冲区buf初始化为0
     char buf[1024]={0},tmp[1024]={0};

    fp=fopen ("C:\\doubuf.txt","rb+");

    //  设置文件fp缓冲区buf,全缓冲,大小为1024字节
     setvbuf(fp,buf,_IOFBF,1024);

    //  fprintf 函数对数据123进行二次处理(即格式化)写入文件:(此时数据被放入缓冲buf)
     fprintf (fp,"123 ");

    //  查看buf数据
     printf ("%d,%c,%c\n",strlen(buf),buf[0],buf[1]);

    //  此时fscanf函数执行失败,因为先前数据还没有写入文件
       // fscanf(fp,"%s",tmp);

    //  刷新缓冲,将数据写入文件,文件位置指针offset到达文件尾。
     fflush(fp);

    //  文件位置指针offset在文件尾,fscanf函数又一次执行失败。
       // fscanf(fp,"%s",tmp);

    //  将文件位置指针offset移到距文件开始处0字节。
     fseek(fp,0,SEEK_SET);

    //  从文件中读取字符串存入tmp数组
     fscanf(fp,"%s",tmp);

    //  查看tmp数据
     printf ("%d,%c,%c\n",strlen(tmp),tmp[0],tmp[1]);

    return 0;
}



再对缓冲区跟踪,发现读写使用同一个缓冲区的,并且每隔4个字节后就会刷新缓冲区,我的平台是win7_64,测试环境GCC4.45  VC2010
[/size2]#include <stdlib.h>
#include <stdio.h>
#define print_buf printf ("fp->_base=%p缓冲区基地址\nfp->_ptr=%p指向当前缓冲区内容的指针\nfp->_cnt=%d如果是输入缓冲区就显示现在缓冲区里还有多少个有效数据\nfp->_bufsiz=%d缓冲区总大小\nfp->_file=%d这个是设备句柄\nfp->_flag=%d标志位可写可读的模式\n\n",fp->_base,fp->_ptr,fp->_cnt,fp->_bufsiz,fp->_file,fp->_flag)

int main( void )
{
    FILE *fp=NULL;
    char buf[4096]={0};
    int i = 99 , t ;
    fp = fopen("abc", "wb");
    fwrite(&i, sizeof(int), 1, fp);
    fclose(fp);

    fp = fopen("abc", "rb+");
    setvbuf (fp,buf,_IOFBF,1024);
    while ( fread(&t, sizeof(int), 1, fp) ) // 读一个数放在t中
    {
        printf ("offset:%lu\n", ftell(fp)); // 读取操作后,查看文件offset
        print_buf; // 查看缓冲区信息
        fseek(fp,-4 ,SEEK_CUR);//退回原来的位置
        fwrite(&i,sizeof i,1,fp) ;// 写入一个整型量i 到文件;
        // fflush(fp);
        printf ("offset:%lu\n", ftell(fp)); // 写入操作后,查看文件offset
        print_buf; // 查看缓冲区信息
        system ("pause"); // windows系统按任意键断续观察每次的变化
        i = t ;
    }
}

望大神门指点

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
2 [报告]
发表于 2012-08-24 23:40 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
3 [报告]
发表于 2012-08-24 23:43 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP