LINUX.ORG.RU

не понимаю, как работает fgetln() :(


0

0

Написал две функции: отдельно для чтения стандартного ввода и отдельно для чтения файла...

char *freadline(FILE * fp)
{
char *s,*f;
int len;
s=fgetln(fp, &len);
if (s==NULL) return NULL;
if (s[len-1]=='\n') len--;
f=(char*)malloc(len+1);
strncpy(f,s,len);
f[len]='\0';
return f;
}

char *readline()
{
char *s,*f;
int len;
s=fgetln(stdin, &len);
if (s==NULL) return NULL;
if (s[len-1]=='\n') len--;
f=(char*)malloc(len+1);
strncpy(f,s,len);
f[len]='\0';
return f;
}

С чтением stdin никаких проблем. Когда читаю файл... он его сразу весь записывает в память... получается что-то вроде такого:
<...>
141 s=fgetln(fp, &len);
(gdb) n
142 if (s==NULL) return NULL;
(gdb) p s
$1 = 0x804f004 "asdf\nbd:\n10-23-122\n\nnm:\nqwerq\ndb:\n10-21-532\n"

а я хотел по строкам, как это происходит с stdin... в чем разница? чего я не понял?... объясните plz чего да как...


и второе: почему не работает стандартная функция readline();?

#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
main() {printf("%s\n",readline("")); return 0;}

:!gcc test.c -o test
/tmp/ccjvdCR5.o(.text+0x28): In function `main':
: undefined reference to `readline'


1) а что это за fgetln ? первый раз слышу о ней как о стандартной.. видимо нечто самодельное ? там то и сидит ашипка ;-) Есть в libc функция getline - она как раз и должна делать то, что вы хотите.

2) чтобы работал readline нужна библиотека readline, то есть надо : gcc test.c -lreadline

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

FGETLN(3) FreeBSD Library Functions Manual FGETLN(3)

NAME
fgetln -- get a line from a stream

LIBRARY
Standard C Library (libc, -lc)

SYNOPSIS
#include <stdio.h>

char *
fgetln(FILE *stream, size_t *len);

а вот по getline никакого мана не нашел:(...
видимо придется пользоваться fscanf...

thnx

CAT_XP
() автор топика
Ответ на: комментарий от CAT_XP

незнаю, как там в BSD, но в libc она присутствует ;-)
(далее - выдержки из man 3 getline)

NAME
       getline, getdelim - delimited string input

SYNOPSIS
       #define _GNU_SOURCE
       #include <stdio.h>

       ssize_t getline(char **lineptr, size_t *n, FILE *stream);
       ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream);

DESCRIPTION
       getline()  reads an entire line, storing the address of the buffer con-
       taining the text into *lineptr.   The  buffer  is  null-terminated  and
       includes the newline character, if a newline delimiter was found.

------ skipped -------

CONFORMING TO
       Both  getline()  and getdelim() are GNU extensions.  They are available
       since libc 4.6.27.




MKuznetsov ★★★★★
()
Ответ на: комментарий от CAT_XP

fscanf - не способ чтобы считывать построчно из потока ;-)

вот - быстренько набросал функцию,
которая долна делать то что вы хотите..точнее просто демонстрирует общий принцип..
возможно - поможет.
(предупрежаю сразу - код не тестировался, написан с руки,
просто показать принцип построчного чтения)

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define STRING_INCREMENT 64

char *my_getline(FILE *f) {
	char *str;
	size_t str_size;
	size_t str_len;
	/* allocate initial pie */
	str_size=STRING_INCREMENT;
	str_len=0;
	str=(char *)malloc(sizeof(char)*str_size);
	while (!feof(f)) {
		/* read pie */
		char *ptr;
		ptr=fgets(str+str_len,str_size-str_len,f);
		if (ptr==NULL) 
			break;
		str_len+=strlen(str+str_len);
		/* if need - enlarge string */
		if (str_len==str_size && str[str_len-1]!='\n') {
			str_size+=STRING_INCREMENT;
			str=realloc(str,str_size);
		}
	}
	if (str_len==NULL) {
		free(str);
		return NULL;
	}
	/* remove trailing spaces */
	while (str_len && isspace(str[str_len-1]))
		str_len--;
	str[str_len]=0;
	return str;
}

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.