Printf печатает мусор после вызова read(). Смещение всегда печатается как 0

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <stdint.h>

int main()
{
    int file;
    off_t offset;

    if((file=open("testfile.txt",O_RDONLY)) < -1)
            return 1;

    char buffer[19];

    if(read(file,buffer,19) != 19)  return 1;
    fprintf(stdout,"%s\n",buffer);


    if(offset = lseek(file,-19,SEEK_END) < 0) return 1;
    fprintf(stdout,"%jd\n",(intmax_t)offset);

    if(read(file,buffer,19) != 19)  return 1;
    fprintf(stdout,"%s\n",buffer);

    return 0;
}

Выход выглядит следующим образом:

Это тестовый файл

0

это тестовый файл

testfile.txt:

Это тестовый файл. Тестирование работы SEEK_END. Это тестовый файл.

Я пробовал другое форматирование для смещения, например,% ld,% d, но вывод остается прежним. Не могу понять, почему мусор появляется в конце первой и последней строки. Пожалуйста помоги.

3 ответа

Вам нужно оставить место для символа конца строки, '\0';

Так сделай char buffer[19];char buffer[20]; затем также добавьте buffer[19] = '\0'; Помните, что это нулевой счет. Тогда у него не должно быть мусорных данных.

Причина в том, что printf не знает, где находится конец массива символов. Таким образом, он продолжает печатать, пока не найдет '\ 0' в мусорной памяти.

read не знает ничего о строках, она читает байты из файла. так что если вы читаете в 19 байтах в "буфер" и нет завершающего \0, то это неверная строка.

Таким образом, либо вы должны убедиться, что ваш буфер равен 0, либо распечатать только первые 19 байтов, например printf( "%.*s", sizeof(buffer), buffer ); или расширить буфер для \0, например char buffer[20] = {0};

Вы также должны открыть файл, как этот, чтобы убедиться, что lseek работает (файл должен быть открыт в двоичном режиме)

if((file=open("testfile.txt",O_RDONLY|O_BINARY)) == -1) // returns -1 by failure
{
  perror("testfile.txt"); // to get an error message why it failed.
  return 1;
}

всегда хорошо выдавать сообщение об ошибке, когда что-то не получается, а не просто завершать программу.

Другие ответы уже предлагали решения проблемы с печатью buffer, Этот ответ отвечает на другой вопрос в вашем посте.

Из-за приоритета оператора, линия

if(offset = lseek(file,-19,SEEK_END) < 0) return 1;

эквивалентно:

if(offset = (lseek(file,-19,SEEK_END) < 0)) return 1;

Я уверен, что вы хотели использовать:

if( (offset = lseek(file,-19,SEEK_END)) < 0) return 1;
Другие вопросы по тегам