[英]Read 1 line per file descriptor using static nodes
我正在嘗試一次讀取一行具有不同緩沖區長度的文件。 我正在將文件desc傳遞給get_next_line函數,並將該行分配給指針。 問題是當緩沖區長度很長時,有時它會打印文件的其余部分,而當我傳遞2個不同的文件描述符時,我會遇到段錯誤。 我認為這與將字符串保存在節點中並在fd相同的情況下找到相同的節點有關。 我看不到我在哪里做錯了什么。
get_next_line.c
#include "get_next_line.h"
#include <fcntl.h>
#include <stdio.h>
/*
** CREATE THE NEXT NODE TO ADD TO THE LINKEDLIST.
**
*/
t_node *create_node(char *buffer, int fd)
{
int i;
t_node *new;
i = 0;
while (*buffer != '\n')
buffer++;
if (*buffer == EOF)
return 0;
++buffer;
new = malloc(sizeof(t_node));
new->fd = fd;
new->next = NULL;
new->str = malloc(sizeof(char *));
while (buffer[i] != '\n')
{
new->str[i] = (char)malloc(sizeof(char));
new->str[i] = buffer[i];
i++;
}
return (new);
}
/*
** SEARCH THE LIST FOR FD AND GET THE OVERFLAP STRING FROM
** LAST READ.
*/
char *get_overlap(t_node **root, int fd)
{
t_node *conductor;
if (*root == NULL)
return (NULL);
conductor = *root;
while (conductor->fd != fd && conductor != 0)
conductor = conductor->next;
if (conductor == NULL)
return (NULL);
return (conductor->str);
}
/*
** CALL THE CREATE NODE FUNCTION AND ADD IT TO THE LINKEDLIST.
**
*/
void save_overlap(char buffer[], t_node **root, int fd)
{
t_node **conductor;
t_node *new;
new = create_node(buffer, fd);
if (*root == NULL)
*root = new;
else
{
conductor = root;
while (*conductor != NULL)
{
if ((*conductor)->fd == fd)
{
(*conductor)->str = new->str;
break;
}
if ((*conductor)->next == NULL)
{
(*conductor)->next = new;
break;
}
*conductor = (*conductor)->next;
}
}
}
/*
** PREPEND THE PREVIOUS OVERLAP IN BUFFER TO LINE STRING.
**
*/
void prepend_overlap(char *str, char ***line, int *i)
{
int b = *i;
while (str[b])
{
(**line)[b] = (char)malloc(sizeof(char));
(**line)[b] = str[b];
b++;
}
*i = b;
}
/*
** GET A SINGLE LINE AT A TIME FROM A FILE
** WHILE ALSO KEEPING TRACK OF THE FD.
*/
int get_next_line(const int fd, char **line)
{
char buffer[BUFF_SIZE + 1];
int i;
int j;
char *overlap_str;
static t_node *root;
i = 0;
j = 0;
overlap_str = get_overlap(&root, fd);
if(overlap_str != NULL)
prepend_overlap(overlap_str, &line, &i);
read(fd, buffer, BUFF_SIZE);
while (buffer[j] != '\n')
{
if (j == BUFF_SIZE)
{
(*line)[i] = (char)malloc(sizeof(char));
(*line)[i] = buffer[j];
j = 0;
read(fd, buffer, BUFF_SIZE);
continue;
}
(*line)[i] = (char)malloc(sizeof(char));
(*line)[i] = buffer[j];
i++;
j++;
}
(*line)[i] = '\0';
printf("%s\n", *line);
save_overlap(buffer, &root, fd);
return (0);
}
int main()
{
int fd = open("test", O_RDONLY);
//int fdt = open("test2", O_RDONLY);
char *line;
get_next_line(fd, &line);
get_next_line(fd, &line);
}
get_next_line.h
#ifndef GET_NEXT_LINE_H
# define GET_NEXT_LINE_H
# define BUFF_SIZE 32
#include <fcntl.h>
int get_next_line(const int fd, char **line);
typedef struct s_node
{
int fd;
char *str;
struct s_node *next;
}t_node;
#endif
它與單個文件描述符一起工作,例如,我只能傳遞fd而不是fdt,它將起作用,除非例如,如果我將緩沖區大小設置為120或更大,那么它將輸出比我想要的更多的緩沖區。 我只想要'\\ n'之前的行。
new->str = malloc(sizeof(char *));
...
new->str[i] = (char)malloc(sizeof(char));
我不確定您要在這里做什么。 malloc(N * sizeof(char*))
可用於創建指向“字符數組”的指針數組,其大小為N
基本上就是“字符串數組”或“二維字符數組”。
malloc(sizeof(char))
就是malloc(1)
,或者只是一個字節。 如果new->str
是一個字符數組,則str[i]
已經是一個字節,因此不應使用malloc
進行設置
改為分配一個字符數組:
new->str = malloc(5);
strcpy(new->str, "1234");
這將為str
分配5個字節,然后向其分配“ 1234”,並在末尾添加一個零,共5個字節。
另外,您的鏈接列表沒有頭。 請嘗試以下代碼。
#include <stdlib.h>//*** don't forget the right header files
#include <stdio.h>
#include <string.h>
typedef struct s_node
{
char *str;
struct s_node *next;
}t_node;
void insert_node(t_node** head, char* buf)
{
t_node *node = malloc(sizeof(t_node));
node->next = 0;
//allocate memory for string and copy
node->str = malloc(strlen(buf) + 1); //+1 for nul-terminator
strcpy(node->str, buf);
if (*head == 0)
{
*head = node;
}
else
{
//find the end of the linked list
t_node *tail = *head;
while (tail->next)
tail = tail->next;
//make the end element point to new node
tail->next = node;
}
}
int main()
{
FILE *fd = fopen("test.txt", "r");
if (!fd)
{
printf("file error\n");
return 0;
}
//linked list identifier:
t_node *head = 0;
char buf[1000];
//read the file line by line
while(fscanf(fd, "%999s", buf) > 0)
{
//insert line in to linked list
insert_node(&head, buf);
}
//show the result of the linked list:
t_node *walk = head;
while (walk)
{
printf("[%s]\n", walk->str);
walk = walk->next;
}
return 0;
}
請注意,如果一行或多行的長度超過1000個字符,則以上代碼將失敗。 您可以增加緩沖區的長度,或者有一些方法可以解決這個問題,但是為了使示例簡單,我將其保留下來。
確保編譯器警告級別為4或最大,並確保您處理所有警告和錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.