teddav
teddav

Reputation: 664

C read file and print buffer

I am learning C and I have been trying to read a file and print what I just read. I open the file and need to call another function to read and return the sentence that was just read. My function will return 1 if everything went fine or 0 otherwise. I have been trying to make it work for a while but I really dont get why I cant manage to give line its value. In the main, it always prints (null).

The structure of the project has to stay the same, and I absolutely have to use open and read. Not fopen, or anything else... If someone can explain it to me that would be awesome.

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

#define BUFF_SIZE 50

int     read_buff_size(int const fd, char **line)
{
    char    buf[BUFF_SIZE];
    int     a;

    a = read(fd, buf, BUFF_SIZE);
    buf[a] = '\0';
    *line = strdup(buf);
    return (1);
}

int     main(int ac, char **av)
{
    char    *line;
    int     fd;

    if (ac != 2)
    {
        printf("error");
        return (0);
    }
    else
    {
        if((fd = open(av[1], O_RDONLY)) == -1)
        {
            printf("error");
            return (0);
        }
        else
        {
            if (read_buff_size(fd, &line))
                printf("%s\n", line);
        }
        close(fd);
    }
}

Upvotes: 1

Views: 4824

Answers (3)

Crowman
Crowman

Reputation: 25926

Here:

char    buf[BUFF_SIZE];
int     a;

a = read(fd, buf, BUFF_SIZE);
buf[a] = '\0';

if there are more characters than BUFF_SIZE available to be read, then you will fill your array entirely, and buf[a] will be past the end of your array. You should either increase the size of buf by one character:

char buf[BUFF_SIZE + 1];

or, more logically given your macro name, read one fewer characters:

a = read(fd, buf, BUFF_SIZE - 1);

You should also check the returns from strdup() and read() for errors, as they can both fail.

Upvotes: 2

Petr Skocik
Petr Skocik

Reputation: 60107

Keep it simple and take a look at:

https://github.com/mantovani/apue/blob/c47b4b1539d098c153edde8ff6400b8272acb709/mycat/mycat.c

(Archive form straight from the source: http://www.kohala.com/start/apue.tar.Z)

#define BUFFSIZE    8192

int main(void){
    int     n;
    char    buf[BUFFSIZE];

    while ( (n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            err_sys("write error");

    if (n < 0)
        err_sys("read error");

    exit(0);
}

No need to use the heap (strdup). Just write your buffer to STDOUT_FILENO (=1) for as long as read returns a value that's greater than 0. If you end with read returning 0, the whole file has been read.

Upvotes: 0

Alex Zaharov
Alex Zaharov

Reputation: 69

read(fd, buf, BUFF_SIZE); //UB if string is same or longer as BUFF_SIZE

u need +1 byte to store 0, so use BUFF_SIZE - 1 on reading or +1 on array allocation...also you should check all returned values and if something failed - return 0

Upvotes: 0

Related Questions