C,unix并用write(),open()和lseek()覆盖一个char

时间:2012-04-13 05:36:54

标签: c file seek

我需要用'?'替换文本文件中的字符。它没有按预期工作。

该文件的内容为'abc'(不含引号),我必须使用unix系统调用:lseek(),open()和write()。我不能使用标准的C文件I / O功能。

计划最终将其扩展为更广泛的“查找和替换”实用程序。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(){

int file = open("data", O_RDWR); //open file with contents 'abc'
lseek(file,0,0); //positions at first char at beginnging of file. 
char buffer;
read(file,&buffer, sizeof(buffer));
printf("%c\n", buffer); // text file containing 'abc', it prints 'a'. 

if (buffer == 'a'){
    char copy = '?';
    write(file,&copy,1); //text file containing 'abc' puts '?' were 'b' is.
    }

close(file);
}

文件“数据”包含 abc ,我想用替换 a 并将其设为?bc 但我得到 a?c

read()正在读取正确的字符,但 write()正在写入下一个字符。 为什么是这样?

一直在谷歌搜索几个小时。

谢谢

3 个答案:

答案 0 :(得分:5)

答案实际上是以某种方式嵌入到您自己的代码中。

lseek之后的open调用不是必需的,因为当您第一次open文件时,当前搜索偏移量为零。

在每次成功readwrite操作后,搜索偏移量向前移动读取/写入的字节数。 (如果您将O_APPEND添加到open,搜索偏移量也会在每次写入之前移动到当前文件结束时,但此时不相关。)

由于您成功read一个字节,您的搜索偏移量从0移到1.如果要将其重新置于0,则必须手动执行此操作。

(当然,您还应该检查每个操作是否成功,但我认为您为了简洁而将其留下了。)

答案 1 :(得分:0)

您对read()的调用将文件指针向前移动一个字节 - 即从0到1.由于您使用相同的文件描述符(“int file = ...”)进行读写,因此位置为阅读和写作也一样。

要写入刚刚读取的字节,需要在

之后lseek()返回一个字节
(buffer == 'a') 

成真。

答案 2 :(得分:0)

lseek在错误的地方。一旦发现“a”,它会写'?'在下一个可用的位置(恰好覆盖'b')。要修复,您需要在编写之前使用lseek更改当前位置。

if (buffer == 'a'){
char copy = '?';
lseek(file,0,SEEK_SET); //positions at first char at beginnging of file.
write(file,&copy,1); //text file containing 'abc' puts '?' were 'b' is.
}