Thread: Read function

  1. #1
    Registered User
    Join Date
    Aug 2012
    Posts
    38

    Red face Read function

    Hello Cboarders,

    Would love to get some help understanding the read function.

    I am attempting to use read() to read line by line.

    My code is structured as follows.
    Code:
    int some_function(const int fd, char **line)
    {
    while ((ret = read(fd, buf, BUFF_SIZE)) > 0)
    { }
    return (int);
    }
    If for example the file i am reading contains "HELLO\n!WORLD!", and I am reading 8 bytes.. I am losing part of the second line on the second time that I call the function...

    I have done some research and realise that lseek is a way to change the offset of the fd being read.. We have been asked to do this without the use of any supplementary library functions.

    Would love some guidance!

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    I don't understand your question. Please post a complete program and a more specific question.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Tigertan
    If for example the file i am reading contains "HELLO\n!WORLD!", and I am reading 8 bytes.. I am losing part of the second line on the second time that I call the function...
    Let's change the example: suppose the file that you are reading contains "a\nwhole\nnew\nworld". If BUFF_SIZE == 8, then clearly you'll be reading two lines at once (i.e., "a\nwhole\n"). How are you handling that? My guess is that you aren't handling that, e.g., you're just taking the portion of what was read until the first '\n' and discarding the rest, hence your problem. Of course, as john.c observed, you need to post a complete program; at this stage I'm just guessing as to what is your problem.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Aug 2012
    Posts
    38
    Quote Originally Posted by john.c View Post
    I don't understand your question. Please post a complete program and a more specific question.
    Sorry for not being clear!

    Here is the full code:
    Code:
     
    #include "line_by_line.h"
    #include <stdio.h>
    
    static int		check_line(char *str)
    {
    		int i;
    
    		i = 0;
    		while (str)
    		{
    				if (str[i] == '\n')
    						return (1);
    				i++;
    		}
    		return (0);
    }
    
    static char		*ft_trim_line(char *str)
    {
    		char	*ret;
    		int		i;
    
    		i = 0;
    		while (str[i] != '\n')
    				i++;
    		ret = ft_strnew(i);
    		i = 0;
    		while (str[i] != '\n')
    		{
    				ret[i] = str[i];
    				i++;
    		}
    		ret[i] = '\0';
    		return (ret);
    }
    
    static char		*ft_prep_next(char *str)
    {
    	int		i;
    	char	*ret;
    	i = 0;
    
    	while (str[i] != '\n')
    		i++;
    	ret = ft_strsub(str, i + 1, ft_strlen(str) - 1); 
    	return (ret);
    }
    
    int			line_by_line(const int fd, char **line)
    {
    		char buf[BUFF_SIZE + 1];
    		char *str;
    		char *tmp;
    		char c;
    		ssize_t ret;
    
    		str = ft_memalloc(1);
    		while ((ret = read(fd, buf, BUFF_SIZE)) > 0)
    		{
    				if (ret == -1)
    						return (-1);
    				buf[BUFF_SIZE] = '\0';
    				str = ft_strjoin(str, buf);
    				if (check_line(str))
    				{
    						*line = ft_trim_line(buf);
    						//printf("BUF IS\n\n<<%s>>\n\n",buf);
    						//*buf = *buf - 3;
    						//tmp = ft_prep_next(buf);
    						ft_strclr(buf);
    						//buf = ft_strdup(tmp);
    						return(1);
    				}
    		}
    		if (ret == 1)
    				return (1);
    		//	if (ret == EOF)
    		//	return (0);
    		else
    				return (-1);
    }
    Lets say my BUFF_SIZE is 8, in my first read, I am reading into the second line.. The next time I call the function line_by_line, the function returns only part of the second line..

    My main is:
    Code:
    #include "line_by_line.h"
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    
    /*int main(int argc, char **argv)
    {
    		int i;
    		int fd;
    		char *line;
    		line = NULL;
    		i = 0;
    		argc = 0;
    		if (!(fd = open(argv[1], O_RDONLY)))
    				return (0);
    		while ((i = line_by_line(fd, &line)) > 0)
    		{
    				printf("%s\n", line);
    		}
    		if (close(fd) == -1)
    		{
    				return (0);
    		}
    		return (0);
    }*/
    
    int			main(int argc, char **argv)
    {
    		char	*line;
    		int		fd;
    		int		code;
    		int		len;
    		int		i;
    
    		i = 1;
    		printf("BUFF_SIZE = %d\n", BUFF_SIZE);
    		while (i < argc)
    		{
    				if ((fd = open(argv[i], O_RDONLY)) == -1)
    						printf("Error: Can't open file");
    				while ((code = line_by_line(fd, &line)) > 0)
    				{
    						len = ft_strlen(line);
    						printf("%d - %d - |%s|\n", code, len, line);
    						free(line);
    				}
    				i++;
    				if (i < argc)
    		}
    		printf("LAST %d - |%s|\n", code, line);
    		return (0);
    }
    I'm using my own static library too..

  5. #5
    Registered User
    Join Date
    Aug 2012
    Posts
    38
    Hi there,
    Thanks for your reply. Yes you're right.. I am searching through the bug after the first read of size BUFF_SIZE and am return the first line.. The rest is discarded..

    When the function is called the next time, it reads from BUFF_SIZE,.. even if it has skipped some lines :/ :/. Stück trying to save the information which was read in the first go, but that makes up the next line (lines)

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Quote Originally Posted by Tigertan View Post
    Sorry for not being clear!
    laserlight was able to decode your meaning pretty handily, and after reading laserlight's post I thought for sure that's what you meant.

    So you need to be able to save the previous "extra" part between reads, which means you'll need a static buffer. So your line_by_line routine will want to maintain a static buffer that it provides the line from and only fills up again when it's empty.

    So if it happens to read in two-and-a-bit lines worth of data the first time, it will return just the first line. The next time it's called it won't read any new data at all, but just return the second line. The third time it's called it will not only need to return the partial line that it has in the buffer but also read another buffer-full and finish off the line from that.

    It's also possible that a line is longer than a buffer-full and so will take more than one read to satisfy.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  7. #7
    Registered User
    Join Date
    Aug 2012
    Posts
    38
    Quote Originally Posted by john.c View Post
    laserlight was able to decode your meaning pretty handily, and after reading laserlight's post I thought for sure that's what you meant.

    So you need to be able to save the previous "extra" part between reads, which means you'll need a static buffer. So your line_by_line routine will want to maintain a static buffer that it provides the line from and only fills up again when it's empty.

    So if it happens to read in two-and-a-bit lines worth of data the first time, it will return just the first line. The next time it's called it won't read any new data at all, but just return the second line. The third time it's called it will not only need to return the partial line that it has in the buffer but also read another buffer-full and finish off the line from that.

    It's also possible that a line is longer than a buffer-full and so will take more than one read to satisfy.
    Cheers John!
    I'm not (yet) familiar with how static buffers are implemented but shall do my research and give it a go! Have clearly understood your explanation. Thanks for putting me on the right track!

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    Quote Originally Posted by Tigertan View Post
    I'm not (yet) familiar with how static buffers are implemented but shall do my research and give it a go! Have clearly understood your explanation.
    The idea is that a variable declared as "static" inside a function retains it's value between calls, unlike so-called "automatic" variables that are kept on the stack and lose their value between calls.
    Code:
    int read_line(int fd, char **line) {
        static char buf[BUFF_SIZE];
        static int bufsize = 0, bufpos = 0;
        
        ...
    }
    Last edited by john.c; 12-23-2017 at 12:41 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Is possible read text form keyboard using read() function?
    By Vanhapolle in forum C Programming
    Replies: 3
    Last Post: 12-08-2013, 11:51 PM
  2. Replies: 7
    Last Post: 12-07-2012, 10:44 PM
  3. read() function
    By tkansara in forum C Programming
    Replies: 1
    Last Post: 06-01-2012, 05:24 PM
  4. Replies: 35
    Last Post: 12-01-2011, 08:31 PM
  5. read function
    By winsonlee in forum C Programming
    Replies: 7
    Last Post: 09-19-2004, 12:12 AM

Tags for this Thread