Printf printing garbage after read() call. The offset is always printed as 0

蹲街弑〆低调 提交于 2019-11-27 08:46:12

问题


#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;
}

The Output is as follows:

This is a test file��

0

his is a test file

��

testfile.txt :

This is a test file Testing how SEEK_END works This is a test file

I have tried different formatting for offset, such as %ld,%d, but the output is still the same. Can't figure out why garbage appears at the end of first line and last line. Please help.


回答1:


You need to leave room for an end of line character, '\0';

So make char buffer[19]; char buffer[20]; then also add buffer[19] = '\0'; - remember it's zero based counting. Then it shouldn't have the garbage data.

The reason is because printf doesn't know where the end is of the character array. So it keeps printing until it finds a '\0' in garbage memory.




回答2:


read does not know anthing about strings, it reads bytes from a file. so if you read in 19 bytes into "buffer" and there is no terminating \0 then it is not a valid string.

So either you need to ensure that your buffer is 0 terminated or print out only the first 19 bytes e.g. printf( "%.*s", sizeof(buffer), buffer ); or extend the buffer for the \0 e.g. char buffer[20] = {0};

You should also open the file like this in order to make sure lseek works (file must be opened in binary mode)

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;
}

it is always good to give an error message when something fails instead of just terminating the program.




回答3:


Other answers have already offered solutions for the problem with printing buffer. This answer addresses the other question in your post.

Due to operator precedence, the line

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

is equivalent to:

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

I am sure you meant to use:

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


来源:https://stackoverflow.com/questions/26858567/printf-printing-garbage-after-read-call-the-offset-is-always-printed-as-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!