Случайные целые числа, поступающие из системного вызова "запись", не распознаются из системного вызова "чтение" в C

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

Проблема в том, что хотя функция записи правильно записывает случайные целые числа (размером 500), функция чтения может извлечь, например, 200 из них, а затем она возвращает мусор для остальных 300. Иногда она возвращает только 10 из них. Каждый раз, когда я запускаю код, он ведет себя по-разному.

Я проверил, что функция "запись" записывает все числа правильно, печатая их в другой файл (например, file1). Но печать чисел, которые возвращает функция "чтение" (например, file2), показала мне, что они не все одинаковые.

Я понял, что если я использую одно число (например, 5) вместо случайного целого числа, все это прекрасно работает. Я много гуглил, проверял, правильно ли открываю / закрываю файлы и не могу решить проблему.

Вот мой код на C. Я удалил некоторые проверки ошибок, чтобы показать вам небольшой скрипт. Не могли бы вы мне помочь?

int main()
{
    srand ( time(NULL) );

    // write
    int fd = open("file_test_1", O_CREAT | O_WRONLY);
    int val;
    if (fd != -1) {
        for(int i=0;i<500;i++){
            val = (int) rand()%500;
           // val = 5;
            write(fd, &val, sizeof(val));
        }
    }
    close(fd);

    FILE * file_check;
    file_check=fopen("file_test_1_check","w");

   // test read
    fd = open("file_test_1", O_RDONLY);
    int new_val;
    int x;
    if (fd != -1) {
        while(  ( x = read(fd, &new_val, sizeof(new_val)) )>0 ){
            fprintf(file_check,"%d\t\t%d\n",new_val, x);
        }

    }
    close(fd);
    fclose(file_check);
    return 0;
}

2 ответа

Решение

Когда вы используете O_CREAT чтобы открыть файл, вам нужно установить права доступа к файлам для последующих пользователей. Вы делаете это, определяя pmode, т.е. ИЛИ используя комбинацию флагов S_IREADS_IWRITE (идти вперед и использовать оба). Кроме того, поскольку вы пишете двоичный файл, это не повредит информированию системы с помощью O_BINARY, Так правильно open было бы:

int fd = open("file_test_1", O_BINARY | O_CREAT | O_WRONLY | S_IREAD);

Теперь, когда вы снова открываете этот файл, вам действительно нужно открыть его в двоичном виде, поэтому правильное последующее открытие будет:

fd = open("file_test_1", O_RDONLY | O_BINARY);

Ты первый open вызов неверен. За страницу руководства, когда вы проходите O_CREAT в oflag аргумент open, треть mode аргумент обязателен. Это будет режим доступа к файлу. В моей системе open видит 0 для пропущенного третьего аргумента (оставшееся значение в регистре или в стеке), поэтому следующий open (прочитать файл) не удается.

Другие вопросы по тегам