2013-11-14 12 views
1

Я пытаюсь создать программу, которая будет копировать 512 байт из 1 файла в другой с использованием указанных системных вызовов (я мог бы сделать пару буферов, memcpy (), а затем fwrite(), но я хочу попрактиковаться с Unix-специфическим уровнем ввода-вывода низкого уровня). Вот начало кода:open() и read() системные вызовы ... программа не выполняется

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

int main(int argc, char **argv) 
{ 
    int src, dest, bytes_read; 
    char tmp_buf[512]; 

    if (argc < 3) 
     printf("Needs 2 arguments."); 

    printf("And this message I for some reason don't see.... o_O"); 

    if ((src = open(argv[1], O_RDWR, 0)) == -1 || (dest = open(argv[2], O_CREAT, 0)) == -1) 
     perror("Error"); 

    while ((bytes_read = read(src, tmp_buf, 512)) != -1) 
     write(dest, tmp_buf, 512); 

    return 0; 
} 

Я знаю, что я не иметь дело с тем, что файл читать не собирается быть кратным 512 размера. Но сначала мне действительно нужно выяснить 2 вещи:

  1. Почему мое сообщение не появляется? Отсутствует также ошибка сегментации, поэтому в итоге мне остается только C-c из программы

  2. Как именно работают эти функции низкого уровня? Есть ли указатель, который сдвигается с каждым системным вызовом, например, если мы использовали файл FILE * с файлом fwrite, где наш * файл будет автоматически увеличиваться, или нам нужно увеличивать указатель файла вручную? Если да, то каким образом мы могли бы получить доступ к нему при условии, что open() и т. Д. Никогда не укажет указатель на файл, а не только идентификатор файла?

Любая помощь будет замечательной. Пожалуйста. Спасибо!

ответ

3

Причина, по которой вы не видите напечатанное сообщение, состоит в том, что вы не очищаете буферы. Текст должен показать, как только программа выполнена (что никогда не происходит, и почему это так, объясняется в комментарии трояном и в ответе paxdiablo). Просто добавьте новую строку в конце строк, чтобы увидеть их.

И у вас есть серьезная ошибка в цикле чтения/записи. Если вы прочитали меньше, чем запрошенные 512 байт, вы все равно напишите 512 байт.

Кроме того, пока вы проверяете наличие ошибок при открытии, вы не знаете , который из open вызовов, которые не удались. И вы продолжаете программу, даже если вы получите сообщение об ошибке.

И, наконец, функции очень просты: они вызывают функцию в ядре, которая обрабатывает все для вас. Если вы читаете X байты, указатель файла перемещается вперед по X байтам после завершения вызова.

+1

также 'чтения()' 'возвратит 0' на EOF, которая не проверяется. – trojanfoe

+0

большое спасибо. Я рассмотрю эти проблемы с открытым вызовом, я знаю, что это жуткий ход. Что касается реализации функций, спасибо за рассказ. Я боялся, что он всегда будет указывать на начало – x86ris

2

Причина, по которой вы не видите сообщение, состоит в том, что вы находитесь в режиме буферизации. Он будет очищаться только при обнаружении символа новой строки.

Что касается того, почему он ждет вас навсегда, вы получите только -1 на ошибке .

Успешно чтение до конца файла даст вам 0 возвращаемое значение.

Лучше петля будет вдоль линий:

int bytes_left = 512; 
while ((bytes_left > 0) { 
    bytes_read = read(src, tmp_buf, bytes_left); 
    if (bytes_read < 1) break; 
    write(dest, tmp_buf, bytes_read); 
    bytes_left -= bytes_read; 
} 
if (bytes_left < 0) 
    ; // error of some sort 

 Смежные вопросы

  • Нет связанных вопросов^_^