5

我需要将文本文件中的 a 字符替换为“?”。它没有按预期工作。

该文件的内容为“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,我想并使其成为?bc,但我得到了一个?c

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

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

谢谢

4

3 回答 3

5

在某种程度上,答案实际上嵌入在您自己的代码中。

不需要您之后立即执行的lseek调用,open因为当您第open一个文件时,当前的查找偏移量为零。

每次成功readwrite操作后,寻道偏移量向前移动读取/写入的字节数。(如果您添加O_APPEND到您open的查找偏移量也将在每次写入之前移动到当前文件末尾,但这与此时无​​关。)

由于您成功read了一个字节,因此您的查找偏移量从 0 移动到 1。如果要将其放回 0,则必须手动执行此操作。

(当然,您还应该检查每个操作是否确实成功,但我假设您在此处为简洁起见忽略了这一点。)

于 2012-04-13T05:42:19.697 回答
0

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

要覆盖刚刚读取的字节,您需要在 lseek() 之后返回一个字节

(buffer == 'a') 

成真。

于 2012-04-13T05:43:44.283 回答
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.
}
于 2016-04-14T08:12:20.253 回答