Обычно вам нужно использовать while
петли (или вообще какой-то тип l oop) с read
и write
, потому что, как вы должны знать на странице руководства (man 2 read
) ):
RETURN VALUE
On success, the number of bytes read is returned (zero indicates end
of file), and the file position is advanced by this number. It is
not an error if this number is smaller than the number of bytes
requested; this may happen for example because fewer bytes are
actually available right now (maybe because we were close to end-of-
file, or because we are reading from a pipe, or from a terminal), or
because read() was interrupted by a signal. See also NOTES.
Поэтому, если вы хотите прочитать больше 1 байта, вам нужно сделать это в al oop, потому что read
всегда может процесс меньше , чем запрашиваемая сумма.
Аналогично, write
также может обрабатывать меньше, чем запрошенный размер (см. man 2 write
):
RETURN VALUE
On success, the number of bytes written is returned (zero indicates nothing was written). It is not an error if this
number is smaller than the number of bytes requested; this may happen for example because the disk device was filled.
See also NOTES.
On error, -1 is returned, and errno is set appropriately.
Единственная разница здесь, когда write
возвращает 0
, это не ошибка или индикатор конца файла, вы должны просто повторить запись.
Ваш код почти правильный, поскольку он использует al oop продолжать чтение, пока не останется больше байтов для чтения (когда read
возвращает 0
), но есть две проблемы:
- Вы должны проверять ошибки после
read
(rlen < 0
). - Когда вы используете
write
, вы также должны добавить туда al oop, потому что, как я только что сказал, даже write
может обработать меньше запрошенного количества байтов.
Правильная версия вашего кода будет:
#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 256
int main(int argc, char *argv[])
{
char buf[BUF_SIZE];
ssize_t rlen, wlen, written;
char from, to;
int i;
from = 'e';
to = 'a';
while (1) {
rlen = read(0, buf, sizeof(buf));
if (rlen < 0) {
perror("read failed");
return 1;
} else if (rlen == 0) {
return 0;
}
for (i = 0; i < rlen; i++) {
if (buf[i] == from)
buf[i] = to;
}
for (written = 0; written < rlen; written += wlen) {
wlen = write(1, buf + written, rlen - written);
if (wlen < 0) {
perror("write failed");
return 1;
}
}
}
return 0;
}