Solved

File Manipulation

Posted on 2003-11-06
7
208 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
  • 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 45

Expert Comment

by:Kdo
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

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 50 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
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…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

743 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now