-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_next_line.c
135 lines (125 loc) · 4.09 KB
/
get_next_line.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maceccar <maceccar@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/02/07 15:56:48 by maceccar #+# #+# */
/* Updated: 2024/02/07 15:56:48 by maceccar ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
char *read_line(int fd, char *reminder);
char *format_result(char *reminder);
char *format_new_reminder(char *reminder);
// Legge e aggiunge alla stringa main finchè non viene letto uno
// '\n' oppure il file è finito
// Estrae la stringa risultante da quella main(reminder)
// Area il nuove reminder eliminando la linea appena eliminata, (substring?)
char *get_next_line(int fd)
{
static char *reminder;
char *output;
if (fd < 0 || BUFFER_SIZE <= 0)
return (0);
reminder = read_line(fd, reminder);
if (!reminder)
return (NULL);
output = format_result(reminder);
reminder = format_new_reminder(reminder);
return (output);
}
// Buffer viene usata solo come variabile d'appoggio durante la lettura
// Alloca per buffer_size +1(\n)
// 'read_bytes' inizializzato ad uno per 'assecondare' il ciclo successivo
// While la stringa 'main' non contiene uno '\n' &&
// il numero di byte letti è != 0 cioè quando si arriva alla fine del file
// Controllo che il numero di byte letti non sia < 0 => errore
// Null termina la stringa
// Aggiunge alla stringa grande il buffer letto
char *read_line(int fd, char *reminder)
{
char *buffer;
int read_bytes;
buffer = malloc((BUFFER_SIZE + 1) * sizeof(char));
if (!buffer)
return (NULL);
read_bytes = 1;
while (!ft_strchr(reminder, '\n') && read_bytes != 0)
{
read_bytes = read(fd, buffer, BUFFER_SIZE);
if (read_bytes < 0)
{
free(reminder);
free(buffer);
return (NULL);
}
buffer[read_bytes] = '\0';
reminder = ft_strjoin_free_s1(reminder, buffer);
if (!reminder)
return (free(buffer), NULL);
}
return (free(buffer), reminder);
}
// Se non esiste reminder nulla da restituire perchè la stringa è vuota
// Conta il numero dei caratteri del risultato e lo alloca +1(\n) +1(\0)
// Copia il reminder result fino allo '\n' o finchè non è finita
// Se trova uno \n lo aggiunge
// Infine aggiunge lo \0
char *format_result(char *reminder)
{
char *result;
int i;
i = 0;
if (!reminder[i])
return (NULL);
while (reminder[i] && reminder[i] != '\n')
i++;
result = (char *)malloc(sizeof(char) * (i + 2));
if (!result)
return (NULL);
i = 0;
while (reminder[i] && reminder[i] != '\n')
{
result[i] = reminder[i];
i++;
}
if (reminder[i] == '\n')
{
result[i] = reminder[i];
i++;
}
result[i] = '\0';
return (result);
}
// Arrova allo \n (fine della stringa di output) o alla fine della string
// Se non c'è più niente vuol dire che il reminder deve essere vuoto
// 'new_reminder' allocato per la lunghezza totale - lunghezza
// della stringa risultante +1(\0)
// i++ per oltrapassare lo '\n' nel vecchio reminder (fine dell'output)
// Liberato il vecchio reminder
char *format_new_reminder(char *reminder)
{
char *new_reminder;
int i;
int j;
i = 0;
while (reminder[i] && reminder[i] != '\n')
i++;
if (!reminder[i])
{
free(reminder);
return (NULL);
}
new_reminder = (char *)malloc(sizeof(char) * (ft_strlen(reminder) - i + 1));
if (!new_reminder)
return (NULL);
i++;
j = 0;
while (reminder[i])
new_reminder[j++] = reminder[i++];
new_reminder[j] = '\0';
free(reminder);
return (new_reminder);
}