当前位置:  技术问答>linux和unix

求教:Unix下用c实现文本文件的随机读写的问题!!!

    来源: 互联网  发布时间:2015-05-01

    本文导语:  问题:有一个文件file1,内容格式为:字段1|字段2|,有n条记录,且记录是无序排列的,现在要求在不改变记录的排序的情况下,将所有字段1相同的记录中的字段2的值也改为相同的。如:原文件内容为: 1101|1| 1002|2| 110...

问题:有一个文件file1,内容格式为:字段1|字段2|,有n条记录,且记录是无序排列的,现在要求在不改变记录的排序的情况下,将所有字段1相同的记录中的字段2的值也改为相同的。如:原文件内容为:
1101|1|
1002|2|
1101|2|
1002|3|
要求修改后为:
1101|1|
1002|2|
1101|1|
1002|2|
请教该如何实现?
我想用双重循环来读取文件,然后依次找到字段1相同的记录,然后修改记录的字段2
的值,写入原位置,可是我不清楚怎么将字段2的值修改后再写入原来的位置?
我用fgets来逐行读取记录的,可是怎么得到字段2的起始位置?

|

/* recordio */

#include 
#include 
#include 
#include 
#include "recordio.h"


int initrecord(const char* pathname, unsigned int reclen)
{
int fd;
int rs;
RECORDINFO info;

if ( (fd = open(pathname, O_RDWR|O_CREAT, 0660)) == -1 ) {

perror("Fail to open file for initializing record");
return -1;
}

if ( (rs = read(fd, &info, sizeof(RECORDINFO))) == -1 ) {

perror("Fail to read record info for initializing record");
return -1;
}

if ( rs == 0 ) {

info.reclen = reclen;
info.recnum = 0;

if ( write(fd, &info, sizeof(RECORDINFO)) == -1 ) {

perror("Fail to write record info for initializing record");
return -1;
}
}

close(fd);
return 0;
}


int addrecord(const char* pathname, void* buf, unsigned int reclen, unsigned int recnum)
{
int fd;
int rs;
struct flock lock;

lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;

if ( (fd = open(pathname, O_WRONLY|O_APPEND)) == -1 ) {

perror("Fail to open file for adding record");
return -1;
}

if ( fcntl(fd, F_SETLKW, &lock) == -1 ) {

      perror("Fail to lock file for adding record");
return -1;
}

        lock.l_type = F_UNLCK;

rs = write(fd, buf, reclen * recnum);

if ( fcntl(fd, F_SETLKW, &lock) == -1 ) {

perror("Fail to unlock file for adding record");
return -1;
}

close(fd);
return rs;
}


int getrecord(const char* pathname, void* buf, unsigned int reclen, unsigned int recnum)
{
int fd;
int len;
RECORDINFO info;
struct flock lock;

lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;

if ( (fd = open(pathname, O_RDWR)) == -1 ) {

perror("Fail to open file for geting record");
return -1;
}

if ( fcntl(fd, F_SETLKW, &lock) == -1 ) {

perror("Fail to lock file for geting record");
return -1;
}

lock.l_type = F_UNLCK;

if ( read(fd, &info, sizeof(RECORDINFO)) != sizeof(RECORDINFO) ) {

perror("Fail to read record info");
return -1;
}

if ( info.reclen != reclen ) {

fprintf(stderr, "Invalid reclen parameter n");
return -1;
}

if ( lseek(fd, sizeof(RECORDINFO) + info.reclen * info.recnum, SEEK_SET) == -1 ) {

perror("Fail to seek read position");
return -1;
}

if ( (len = read(fd, buf, reclen * recnum)) == -1 ) {

perror("Fail to get record");
return -1;
}

if ( len == 0 ) {

if ( ftruncate(fd, sizeof(RECORDINFO)) == -1 ) {

perror("Fail to truncate file");
return -1;
}

info.recnum = 0;
if ( lseek(fd, 0, SEEK_SET) == -1 ) {


perror("Fail to return beginning");           
return -1;                 
}

if ( write(fd, &info, sizeof(RECORDINFO)) == -1 ) {

perror("Fail to update record info");
return -1;
        }

 if ( fcntl(fd, F_SETLKW, &lock) == -1 ) {

 perror("Fail to unlock file for geting record");
 return -1;
 }
 
close(fd);
return 0;

} else { 

info.recnum +=  len / info.reclen;

if ( lseek(fd, 0, SEEK_SET) == -1 ) {

perror("Fail to return beginning");
return -1;
}

if ( write(fd, &info, sizeof(RECORDINFO)) == -1 ) {

perror("Fail to update record info");
return -1;
}

if ( fcntl(fd, F_SETLKW, &lock) == -1 ) {
               
     perror("Fail to unlock file for geting record");
return -1;

}

close(fd);
return len;
}

}

               

|
"或者是怎样在用fgets读取了一行记录后再回到该行记录的起始处?这样我就可以用fputs写入修改后的记录了" 
         ftell:获得当前文件位置
         fseek:跳转当前文件位置

|
每条记录是不是都是同样长度的?那就简单多了。
用fseek就行了,比如你上面的例子
首先,估计一个数组arc[7][100];
然后,fgets,每取到一个全新的记录,就添加到arc里,然后fseek(fp, -3, SEEK_SET)(应该是往前回3个吧,你自己再测试一下 :)),然后fputs就可以了。

|
如果要提高效率就
1、导入HASH表
2、多线程对数据进行修改
3、写文件

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 求教求教,shell问题...各位大哥,帮忙下
  • 400分求教: 求教一简单问题,现场给分
  • 高分求教:如何将JAVA文件(.class)制作成可执行文件(.exe),求教方法或工具推荐
  • 急!!求教linux命令的使用:统计出/bin目录中文件的个数,追加到文件filea的结尾
  • 求教:在UNIX中查找包含指定文字的文件名
  • 小白菜求教linux大鸟
  • 紧急求教!究竟Java里面有没有相当于C++的CPOINT的类阿? iis7站长之家
  • 初学者有问题求教!
  • 各路高手请进!高分求教,非常着急!
  • 高分求教的问题(关于SendMail设置)
  • 简单问题:从sun网站上当了个jdk1.4b3,bin后缀,求教怎么安装
  • 求教:知道当前时间,如何得到N天前的时间 ?
  • 求教:switch(condition)中的condition 必须为整型吗?
  • Linux远程访问的问题,高分求教:)
  • 求教:在Linux下如何做代理服务器?
  • 紧急求教!究竟Java里面有没有相当于C++的CPOINT的类阿?
  • 求教JAVA中XML解析问题
  • 50分求教,在JSP里如何将String转换成Double
  • 我刚装好,是不是需要配制环境变量?求教。
  • 400分求教JAVA皮肤的问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3