In get_line
buffer = (char*)malloc(sizeof(char)*bufsize);
strcpy(buffer, "");
, чтобы сделать strcpy , чтобы просто установить первый символ в 0, это сложный способпросто сделайте *buffer = 0;
.
sizeof(char)
1 по определению
вам не нужно выполнять приведение
Также обратите внимание, что если buffer не задан NULL в аргументе, поведение опасно и может быть неопределенным, поскольку код предполагает, что данный буфер имеет по крайней мере LINE_MAX
символ.
В
char character = fgetc(fp);
вы не можете обнаружить EOF, необходимо указать int
In
if(character == '\n') {
break;
Вы пропустили обнаружение EOF
Вы пропустили добавление нулевого символа в конце буфера здесь после в то время как
В
strcat(buffer, character);
это недопустимо, поскольку второй аргумент strcat должен быть char*
, strcat объединить две строки, а не строку с символом
Предположим, что есть strcat для добавления символа таким способом, который будет каждый раз искать конец строки для добавления символа, просто используйте bufread привязку индекса
Поскольку профиль функции равен
int get_line(char* buffer, FILE* fp) {
, когда вы выходите из get_line
, вы потеряли текущее значение buffer , создав утечку памятии в main printf("The string you entered was %s\n", string);
printf нулевой указатель.Чтобы избежать этого, вы можете указать строку в качестве выходного параметра, что позволит вам по-прежнему возвращать новую длину:
Предложение:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <stdbool.h>
size_t get_line(char ** buffer, FILE* fp) {
size_t bufsize = LINE_MAX;
size_t bufread = 0;
*buffer = malloc(bufsize);
if (*buffer == NULL)
return 0;
while (true) {
if (bufread == bufsize) {
bufsize += LINE_MAX;
*buffer = realloc(*buffer, bufsize);
}
int character = fgetc(fp);
if ((character == '\n') || (character == EOF)) {
(*buffer)[bufread] = 0;
/* note you can do : *buffer = realloc(*buffer, bufread + 1); to only use the needed memory */
return bufread;
}
(*buffer)[bufread++] = character;
}
}
int main() {
printf("Enter a string: ");
char * string = NULL;
size_t chars_read = get_line(&string, stdin);
if (string != NULL) {
printf("The number of chars read is %zu\n", chars_read);
printf("The string you entered was '%s'\n", string);
free(string);
}
}
Компиляция и выполнение:
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra p.c
pi@raspberrypi:/tmp $ ./a.out
Enter a string: is it working ?
The number of chars read is 15
The string you entered was 'is it working ?'
pi@raspberrypi:/tmp $ ./a.out
Enter a string:
The number of chars read is 0
The string you entered was ''
И под valgrind :
pi@raspberrypi:/tmp $ valgrind ./a.out
==20382== Memcheck, a memory error detector
==20382== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==20382== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==20382== Command: ./a.out
==20382==
Enter a string: what about memory leak ?
The number of chars read is 24
The string you entered was 'what about memory leak ?'
==20382==
==20382== HEAP SUMMARY:
==20382== in use at exit: 0 bytes in 0 blocks
==20382== total heap usage: 3 allocs, 3 frees, 4,096 bytes allocated
==20382==
==20382== All heap blocks were freed -- no leaks are possible
==20382==
==20382== For counts of detected and suppressed errors, rerun with: -v
==20382== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)