对于这个项目,我需要读取一个文件并在遇到换行符或 EOF 时返回一行。 我的函数正确地执行了此操作,但是当文件具有连续的换行符时,假设为每次连续出现返回一个新行。例如:如果文件是:
1."hello there
2.
3.
4.
5."
它应该返回五行,因为每次遇到换行符时函数都会返回。 但本示例的函数返回两次而不是 5 次。在代码后将给出更多输出。
以下是我认为存在问题的代码部分:
int find_newline(char *buffer) // RETURN POSition WHERE IT FINDS THE FIRST '\N' IN THE BUFFER
{
int i;
i = 0;
if (!buffer)
return (-1);
while (buffer[i])
{
if (buffer[i] == '\n')
return (i);
i++;
}
return (-1);
}
static int update_remainder_buffer(char **buffer, int newline_pos)
{ //IS EXPECTED TO TREAT THE CHARACTERS IN BUFFER AFTER THE NEWLINE, PREP FOR NEXT CALL
int remaining_len;
remaining_len = strlen(*buffer + newline_pos);
if (remaining_len > 0)
memmove(*buffer, *buffer + newline_pos, remaining_len + 1);
else
(*buffer)[0] = '\0';
*buffer = realloc(*buffer, strlen(*buffer), remaining_len + 1);
if (!*buffer)
return (0);
return (1);
}
char *extract_line(char **buffer, int newline_pos)
//EXTRACT BUFFER FROM BEGINNING TO THE POINT WHERE IT FINDS THE NEWLINE. USE UPDATE_REMAINDER_BUFFER AS HELPER
{
char *line;
int line_len;
if ((*buffer)[0] == '\n' && newline_pos >= 0)
{//ISSUE PROBABLY HERE or
line = malloc(2);
line[0] = '\n';
line[1] = '\0';
if (!update_remainder_buffer(buffer, 1))
return (free(line), NULL);
return (line);
}
if (newline_pos == -1)
newline_pos = strlen(*buffer);
line_len = newline_pos;
if ((*buffer)[newline_pos] == '\n')
line_len = newline_pos + 1;
line = malloc(line_len + 1);
if (!line)
return (NULL);
memcpy(line, *buffer, line_len);
line[line_len] = '\0';
if (!update_remainder_buffer(buffer, line_len))
return (free(line), NULL);
return (line);
}
所以基本上我想做的是在开始时检查读取的缓冲区是否以换行符开头,以便我们以换行符的方式返回,以及缓冲区中是否有连续换行符的部分。我添加了一些控件来测试,但弄乱了缓冲区内容,因此我删除了可能会导致更多混乱的 if 和 else,并坚持使用此实现以避免这种情况。这是其余的代码,代码按顺序排列,以及一些输出:
int read_newpiece(int fd, char **buffer)
{
int bytes_readed;
char current_buffer[BUFFER_SIZE + 1];
char *new_buffer;
bytes_readed = read(fd, current_buffer, BUFFER_SIZE);
if (bytes_readed <= 0)
return (bytes_readed);
current_buffer[bytes_readed] = '\0';
if (!*buffer)
{
*buffer = malloc(1);
if (!*buffer)
return (-1);
(*buffer)[0] = '\0';
}
new_buffer = ft_realloc(*buffer, ft_strlen(*buffer),
ft_strlen(*buffer) + bytes_readed + 1);
if (!new_buffer)
return (-1);
*buffer = new_buffer;
strncat(*buffer, current_buffer, bytes_readed);
return (bytes_readed);
}
char *get_next_line(int fd)
{
static char *buffer = NULL;
char *line;
int newline_index;
if (fd < 0 || BUFFER_SIZE <= 0)
return (NULL);
if (!buffer)
{
buffer = malloc(1);
if (!buffer)
return (NULL);
buffer[0] = '\0';
}
newline_index = -1;
while (newline_index == -1 && read_newpiece(fd, &buffer) > 0)
newline_index = find_newline_eof(buffer);
if (newline_index == -1 && (!buffer || buffer[0] == '\0'))
{
free (buffer);
buffer = NULL;
return (NULL);
}
line = extract_line(&buffer, newline_index);
return (line);
}
int main(int ac, char **av)
{
int fd;
char *line;
if (ac < 2)
return (write(1, "Usage: ./a.out <filename>\n", 27));
fd = open(av[1], O_RDONLY);
if (fd <= -1)
return (write(1, "error opening file\n", 20));
while ((line = get_next_line(fd)) != NULL)
{
printf("()%s", line); // () TO KEEP TRACK HOW MANY TIMES A BUFFER IS PRINTED
free (line);
}
close (fd);
return (0);
}
这里仅输出连续的换行符文件,请注意,我使用 () 来跟踪缓冲区返回的次数
输出1:
我预计是“()”的 5 倍。
rache@V:~/programing/42/Common Core/get_next_line/04$ ./a.out multiples_nl.txt
()
()
rache@V:~/programing/42/Common Core/get_next_line/04$
输出2:
再次预期 10 个“()”,但立即返回所有换行符。
rache@V:~/programing/42/Common Core/get_next_line/04$ ./a.out test60.txt
()cinccinccinccinccinccinccinccinccinccinccinccincci
()
rache@V:~/programing/42/Common Core/get_next_line/04$
这个输出更大,所以我留到最后: 这里文件打印完全正确,但是当涉及到底部的 4.1 步骤时,它会立即返回所有其余字符。
rache@V:~/programing/42/Common Core/get_next_line/04$ ./a.out 1-brouette.txt
()Wikipédia l'encyclopédie libre
()
()Rechercher dans Wikipédia
()
()Créer un compte
()
()Outils personnelsreplié
()
()Accueil
()Portails thématiques
()
()Article au hasard
()
()Contact
()
()Contribuer
()
()Débuter sur Wikipédia
()
()-----------------------------------------------------------
()Aide
()Communauté
()Modifications récentes
()Faire un don
()Outils
()Pages liées
()Suivi des pages liées
()Téléverser un fichier
()Pages spéciales
()Lien permanent
()Informations sur la page
()Citer cette page
()Élément Wikidata
()Modifier les liens interlangues
()Imprimer / exporter
()Créer un livre
()Télécharger comme PDF
()Version imprimable
()Dans d’autres projets
()Wikimedia Commons
()ArticleDiscussion
()LireModifierModifier le codeVoir l’historique
()-----------------------------------------------------------
()
()Brouette
()
()C’est un outil ergonomique pour le transport de matériaux ou d’outils sur des terrains qui peuvent être accidentés mais nécessairement peu inclinés. Indispensable sur les chantiers, dans les fermes ou dans les jardins, elle facilite le déplacement de charges qui peuvent être lourdes ou encombrantes. Le principe du levier associé à la position du centre de gravité vers l’aplomb du point d’appui (la roue), lui confère une grande efficacité.
()
()Sommaire
()1 Éléments d’histoire de la brouette
()1.1 La question des origines
()1.2 Une diffusion assez lente
()1.3 La brouette dans les textes
()2 Étude technologique de la brouette
()2.1 Analyse fonctionnelle
()2.1.1 Fonction principale, définition
()2.1.2 Constitution de la solution « brouette »
()2.1.3 Variantes – classification
()2.2 Analyse mécanique
()2.2.1 La roue
()2.2.2 Influence de la position longitudinale de la caisse
()2.2.3 Aptitude au basculement
()2.2.4 Conclusions constructives
()3 Perspectives
()4 Autour de la brouette
()4.1 Dans la littérature et dans les arts
4.2 Polysémie du mot brouette
4.3 Jeux d’enfants (petits ou grands…)
4.4 Décoration
5 En images d’hier et d’aujourd’hui
6 Notes et références
7 Voir aussi
7.1 Bibliographie
7.2 Liens externes
Éléments d’histoire de la brouette
La question des origines
Variantes selon le nombre de roues
Si la brouette selon son étymologie a deux roues, c’est surtout lorsqu’elle n’en a qu’une qu’elle se caractérise comme « brouette. » Toutefois, quand elle a deux roues, celles-ci sont coaxiales.
Critiques : La brouette à deux roues permet de plus grandes contenances, plus stable elle peut se conduire d’une seule main mais elle est très difficile, voire éprouvante, à mener sur les terrains accidentés tandis que la brouette à une roue se joue des irrégularités du terrain. Par ailleurs la place nécessaire pour manœuvrer la brouette à deux roues dépend de la largeur de l’essieu.
rache@V:~/programing/42/Common Core/get_next_line/04$
答案是,如果你想从文件中逐行获取,则不能在代码中使用这一行:
bytes_readed = read(fd, current_buffer, BUFFER_SIZE);
您需要将上面的行更改为如下所示的内容
fgets()
:
bytes_readed = 0;
if (fgets(current_buffer, BUFFER_SIZE, fd))
bytes_readed = strlen(current_buffer);
为了使用
fgets()
,您需要使用fopen()
,而不是open()
。
经过上述修改后,我认为您的代码应该可以按您的预期工作。