如何使用malloc逐行打印文件?理想情况下,我想分配足够的空间来保存文件中的一行,打印,释放它,然后重复该过程。
请包含代码段,谢谢!
这是我到目前为止所做的,但Valgrind说我有内存泄漏。
int main (int argc, char **argv)
{
// char *line = NULL;
char *line;
FILE *fp = fopen(argv[1], "r");
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
line = malloc(1);
while (readline(fp, line)) {
// printf("%s\n", line);
}
free(line);
if (fp != stdin) fclose (fp);
return 0;
}
char *readline (FILE *fp, char *buffer)
{
char ch;
int place = 0;
size_t nchar = 1;
ch = fgetc(fp);
while (ch != '\n' && ch != EOF)
{
nchar++;
(buffer)[place] = ch;
char *tmp = realloc (buffer, nchar);
if (!tmp) {
fprintf (stderr, "error: realloc failed, "
"returning partial buffer.\n");
(buffer)[place] = 0;
return buffer;
}
buffer = tmp;
ch = fgetc(fp);
place++;
}
(buffer)[place] = '\0'; /* nul-terminate */
if (ch == EOF) {
if (strlen(buffer) > 1) {
printf("%s\n", buffer);
}
// free(buffer);
buffer = NULL;
} else {
if (strlen(buffer) > 1) {
printf("%s\n", buffer);
}
}
return buffer;
}
答案 0 :(得分:0)
我就是这样做的:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/******************************************************************************
** Read a line from specified stream into allocated memory.
** (Caller is responsable to free the allocated memory).
**
** Parameters:
** I__fp File stream to read.
** _O_line_A Sets caller's pointer to the allocated memory containing the read line.
** Caller's pointer is set to NULL if a blank line is encountered.
** _O_eof Sets caller's integer value as follows:
** 0 = (FALSE) More lines available to read from file.
** -1 = (TRUE) The end-0f-file was encountered while reading the line.
** Return values:
** 0 Call was successful.
** ENOMEM Could not allocate sufficient memory to read a line.
*/
int ReadLine(
FILE *I__fp,
char **_O_line_A,
int *_O_eof
)
{
int rCode = 0; /* Function return status. 0=SUCCESS. */
char *line_A = NULL; /* Pointer to allocated memory containing line read. */
size_t lineLength = 0; /* Length of the allocated line, not including the termination character. */
int eof = 0; /* End-of-file encountered flag. */
for(;;) /* Loop forever. */
{
int ch;
char *newmem;
ch=fgetc(I__fp); /* Read a single character from the stream. */
if(EOF == ch) /* If the value EOF was read... */
{
eof=(-1); /* ...Set the end-of-file flag */
break; /* ...Break out of the for-loop */
}
if('\n' == ch) /* If a new-line character was read... */
break; /* ...Break out of the for-loop */
/* Allocate additional memory, sufficient to hold all characters so far read,
** plus one for the currently read character,
** plus one for the termination character.
*/
newmem=realloc(line_A, lineLength + 1 + 1);
if(!newmem) /* Ensure that realloc() did not fail. */
{
rCode=ENOMEM;
goto CLEANUP;
}
line_A = newmem; /* Change to newly allocated memory. */
line_A[lineLength++] = ch; /* Append the newly read character to the allocated memory. */
line_A[lineLength] = '\0'; /* Append a string termination character to the allocated memory. */
};
//RESULTS:
/* Set the caller's pointer to the allocated line read from the stream. */
if(_O_line_A) /* Allows the caller to pass in a NULL value for _O_line_A... */
{ /* ...For example, if the content of the line is not wanted by the caller. */
*_O_line_A = line_A;
line_A = NULL;
}
/* Set the caller's eof flag. */
if(_O_eof) /* Allows the caller to pass in a NULL value for _O_eof... */
*_O_eof = eof; /* ...For example, if the caller doesn't need the eof value. */
CLEANUP:
/* It is possible that the caller supplied a "NULL" value for _O_line_A.
** ...If so, line_A will not be NULL.\
** ...In that case, free line_A to eliminate potential memory leak.
*/
if(line_A)
free(line_A);
return(rCode);
}
/******************************************************************************
** Program start.
*/
int main(
int argc,
char **argv)
{
int rCode = 0;
char *line_A = NULL;
FILE *fp_A = NULL;
int eof;
errno=0;
fp_A = fopen(argv[1], "r");
if(!fp_A)
{
fprintf(stderr, "fopen(\"%s\") failed. errno: %d %s\n", argv[1], errno, strerror(errno));
goto CLEANUP;
}
rCode=ReadLine(fp_A, &line_A, &eof); /* Read first line from stream. */
while(!rCode)
{
printf("%s\n", line_A ? line_A : "");
free(line_A); /* Free line memory when finished with it. (after printing, etc.) */
if(eof) /* Break out of the while-loop if this is the last line in the stream. */
break;
rCode=ReadLine(fp_A, &line_A, &eof); /* Read next line from stream. */
}
if(rCode)
fprintf(stderr, "ReadLine() reports: %d %s\n", errno, strerror(errno));
CLEANUP:
if(fp_A && (fp_A != stdin))
{
errno=0;
if(EOF == fclose(fp_A))
fprintf(stderr, "fclose() failed. errno: %d %s\n", errno, strerror(errno));
}
return(rCode);
}