如何使用动态内存分配来通过线路打印文件



如何使用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("%sn", 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] = ''; /* nul-terminate */
    if (ch == EOF) {
        if (strlen(buffer) > 1) {
            printf("%sn", buffer);
        }
        // free(buffer);
        buffer = NULL;
    } else {
        if (strlen(buffer) > 1) {
            printf("%sn", buffer);
        }
    }
    return buffer;
}

这就是我的方式:

#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] = '';   /* 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 %sn", argv[1], errno, strerror(errno));
      goto CLEANUP;
      }
   rCode=ReadLine(fp_A, &line_A, &eof);         /* Read first line from stream. */
   while(!rCode)
      {
      printf("%sn", 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 %sn", errno, strerror(errno));
CLEANUP:
   if(fp_A && (fp_A != stdin))
      {
      errno=0;
      if(EOF == fclose(fp_A))
         fprintf(stderr, "fclose() failed.  errno: %d %sn", errno, strerror(errno));
      }
   return(rCode);
   }

最新更新