Home > Net >  Write into text file line by line c
Write into text file line by line c

Time:11-20

I've written a user space program to read from a kernel device line by line, somehow, the data is always overriden with each read. Can you please tell me how to fix my code?

Here is the code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
 

#define BUFFER_LENGTH 256

int main()

{

  int  ret,fd;
  char buffer[BUFFER_LENGTH];
  FILE * fPtr;
  unsigned int i=0;

  if((fd = open("/dev/show_log_device_dev", O_RDWR)) == -1){
    perror("Failed to open the file");
  }
  //printf("/dev/show_log_device_dev opened.\n");
  //fflush(stdout);

  fPtr = fopen("log.txt", "w ");

  int bytesRead = 0;

  while (bytesRead < sizeof(buffer)) {
    int ret = read(fd, buffer   bytesRead, sizeof(buffer) - bytesRead);
    if (ret == 0)
        break;
    if (ret == -1) {  
      perror("Failed to read the message from the device.");
      return errno;
      /* Handle error */
    }
    bytesRead  = ret; 
    printf("read from /dev/show_log_device_dev. %s\n",buffer);

  }
  if(lseek(fPtr,0,SEEK_SET)!=0) {
    fprintf(fPtr,"%s",buffer);
  }

  fclose(fPtr);
}

I would like the output file "log.txt" to contain all the lines written to buffer with each read line after line sith skip-line between lines. Please show me the proper way to do it inctead of the fprintf attempt I've written above.

Thank you.

CodePudding user response:

char buffer[BUFFER_LENGTH];
while()
{...read(fd, buffer   bytesRead, sizeof(buffer) - bytesRead);}

This line is a major problem. Basically this attempts to store the entire file in to buffer. But buffer has a small size (256 bytes).

If file is too large, read will store 256 in to buffer in the first pass. In the second pass in the loop, read will attempt to add another 256 bytes to the same buffer.

Instead you have to read small chunks and write back within the loop.

fPtr = fopen("log.txt", "w ");

This will open the log file in read/write mode, but you only need to write to it. Since this is a log file, consider using "a" option to append to the log file.

fprintf(fout, "%s", buffer);

When you read the buffer it may not be null terminated. Try fwrite instead, or make sure buffer is null terminated before using fprintf

#define BUFFER_LENGTH 256
int main()
{
    int fd = open("/dev/show_log_device_dev", O_RDONLY);
    if(fd == -1)
    { perror("open failed"); return 0; }

    FILE* fout = fopen("log.txt", "w"); //or "a" to create new file
    if(fout == NULL)
    { close(fd); perror("fopen failed, log.txt is busy!"); return 0; }

    while (1) 
    {
        char buffer[BUFFER_LENGTH];
        int ret = read(fd, buffer, sizeof(buffer));
        if (ret == 0)
            break;
        if (ret == -1) 
        {
            perror("Failed to read the message from the device.");
            return errno;
        }
        fwrite(buffer, 1, ret, fout);
        //fprintf(fout, "%s", buffer);
    }

    fclose(fout);
    close(fd);
    return 0;
}

Note, lseek(fPtr,0,SEEK_SET) is wrong and not necessary. This method is excepts a file descriptor obtained from open. But fPtr is FILE* handle obtained from fopen.

If possible, consider using standard c functions FILE*/fopen for both input and output. This way you will be able to use the same set of functions fopen,fread,fwrite,fclose,fseek,ftell. You only need one header file for this:

#include <stdio.h>

int main()
{
    FILE* fin = fopen("/dev/show_log_device_dev", "r");
    if (!fin)
    { perror("input error"); return 0; }

    FILE* fout = fopen("log.txt", "w"); //or "a" to append to log
    if (!fout) 
    {fclose(fin); perror("output error, log.txt is busy!"); return 0; }

    while (1)
    {
        char buffer[256];
        int ret = fread(buffer, 1, sizeof(buffer), fin);
        if (ret == 0)
            break;
        fwrite(buffer, 1, ret, fout);
    }

    fclose(fout);
    fclose(fin);
    return 0;
}
  • Related