?
Solved

File Manipulation

Posted on 2003-11-06
7
Medium Priority
?
216 Views
Last Modified: 2010-04-15
How to delete the last line of a text file?
Efficient way please. Is it possible to do that without reading the entire file?
0
Comment
Question by:sonic2000
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 9695582
If I assume I understood you properly,

If your file is fixed length line file, then it is

Using fseek ( fp, 0, END)  go to the end of file,
Then as you know the no of bytes in each line [being a fixed length line file],
again use fseek with a negative value of the size of the line.

HTH

Amit
0
 
LVL 10

Expert Comment

by:Sys_Prog
ID: 9695594
sorry, END should be SEEK_END in the above call to fseek
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 9695798

Most of the time you won't know the length of the last line.  In that case you'll have to find it "the hard way" and then delete it by moving EOF with the truncate() function.

There are several ways to do this.  For short files, it's probably easiest to just read through the file, keeping track of the number of bytes read.  But this is not very efficient and will cause quite a delay on large files.  Here's (untested) code to do what you want.


#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define BUFFERL 512  /* Disk I/O is usually in 512 word blocks, so reading 512 words at a time is pretty efficient  */

int FileHandle;

main (int argc, char **argv)
{
  int Buffer[BUFFERL];
  struct stat StatBuff;
  long FileLength;
  long DropCount;   /*  Not really used, but you might want to print it to stderr for debuggin  */
  long FilePosition;
  int   BlockLength;
  int idx;

  FileHandle = open (argv[1], O_RDWR);   /*  Sanity check needed that argv[1] actually exists and could be opened in this mode  */

  stat (argv[1], &StatBuff);  /*  If open() is successful, this should be, too  */
  FileLength = StatBuff.st_size;
  BlockLength = (StatBuff  & 0x7F);  /*  byte count in last 512 word block  */
  if (BlockLength == 0)
    BlockLength = BUFFREL
  DropCount = 0;

  while (FilePosition > 0)
  {
    FilePosition = FileLength - BlockLength;
    Read (FileHandle, Buffer, BlockLength);
    for (idx = BlockLength-1; idx >= 0; idx--)
      if (Buffer[idx] == '\n' || Buffer[idx] ==  '\r')  /*  found a carriage return or a line feed  */
      {
        truncate (FileHandle, FilePosition + idx);
        exit ();
      }
    DropCount += BlockLength;
    BlockLength = BUFFERL;
  }

  /*  no end of line found  */
}


Kent
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:sonic2000
ID: 9699703
SysProg, can you be more specific?
I tried this and it does not work

#include <stdio.h>
#include <string.h>

typedef struct CMD_INFO{
      char cmd[51];
      double startTime;
      double endTime;
      int pid;
} CMD_INFO;


void read_stat();
void delete_last_stat();

int main() {
      delete_last_stat();
      read_stat();
      
      return 1;
}


// read statistics from file
void read_stat() {
      CMD_INFO cmdInfo;
      FILE *fp;
      int i=0;

      fp = fopen(".stats.log", "r+");
      fseek(fp, 0, SEEK_SET);

      fread(&cmdInfo, sizeof(cmdInfo), 1, fp);
      while ( !feof(fp) ) {
            printf("Record %d\n", ++i);
            printf("cmd = %s\n", cmdInfo.cmd);
            printf("startTime = %f\n", cmdInfo.startTime);
            printf("endTime = %f\n", cmdInfo.endTime);
            printf("pid = %d\n\n", cmdInfo.pid);

            fread(&cmdInfo, sizeof(cmdInfo), 1, fp);
      }

      fclose(fp);
}

// Write statistics to file
void delete_last_stat() {
      CMD_INFO cmdInfo;
      FILE *fp;

      fp = fopen(".stats.log", "a+");
      fseek(fp, 0, SEEK_END);
      fseek(fp, (sizeof(cmdInfo))*-1, SEEK_CUR);

      fclose(fp);
}

.stats.log exists and has got contents. Content does not change after I use fseek. My understanding of fseek is to move the file pointer right?
0
 
LVL 10

Accepted Solution

by:
Sys_Prog earned 200 total points
ID: 9699885
I am sorry sonic2000

I mis-read your question. I thought u wanted to read the last line efficiently.

Sorry for that

Yes, fseek is only for moving the file pointer

But Yes, we can continue our apporach

Just use fteel to get the size of       File - Last line

and then use truncate

Here's the code for that

fseek ( fp, (sizeof(cmdInfo))*-1, SEEK_END ) ;
newsize = ftell ( fp ) ;
truncate ( fp, newsize ) ;

Just have a look at help for truncate
HTH

Amit


newsize =
0
 

Author Comment

by:sonic2000
ID: 9699900
thanks for replying.
at this time i have already solved my problem using google :)

I am using ftruncate();
0
 

Author Comment

by:sonic2000
ID: 9699910
but i know you are correct so you get the points.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question