• Welcome to Valhalla Legends Archive.
 

File Manipulation

Started by NicoQwertyu, October 03, 2005, 12:58 PM

Previous topic - Next topic

NicoQwertyu

What's a good way to remove a line from a file (database.txt :P)?  I remember in VB I used to read the file, store the information in an array, then simply rewrite the file.  I don't know how to do that in C, because there's no way for me to know how large to make the array.   Ideas?

MyndFyre

You could read it line-by-line until you reached EOF.  Then restart from the top and read it line-by-line into an array.  Or you could use a std::vector (a dynamic array).  Or you could make one big-ass array of pointers and hope for the best (although this solution is nonoptimal).
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.


shout

void *malloc(size_t length)

Yegg

Reading it line by line into an array is the method I use. However it may be better to use a linked list rather than an array.

MyndFyre

#5
Quote from: NicoQwertyu on October 03, 2005, 01:16 PM
How am I suppost to make an char array without a... uh... hardcoded size?

Did you even read my post?  "Or you could use a std::vector (a dynamic array)."

Here's a website I found using Google searching for std::vector class.

Or you could do what Shout suggested:


char *lines[] = (char**)malloc(max_string_size_per_line * number_of_lines);


It depends if you're using C or C++.  If you're using C, malloc is the right way to go; there's no new operator and no std::vector class.  If you're using C++, use the STL method (std::vector).

**OR** you could create your own dynamic array with a set of structures in a linked list.

struct db_line // node type
{
  db_line *next;
  int lineLength;
  char *line;
}

struct db_list
{
  int number_of_lines;
  db_line *first;
}

db_list createNewList()
{
  db_list db;
  db.number_of_lines = 0;
  db.first = NULL;
  return db;
}

// adds a new line to the end of the list.
void addToList(db_list *list, db_line *line)
{
  if (list == NULL) return;

  if (list->first == NULL)
  {
    list->first = line;
  }
  else
  {
    db_line *cursor = list->first;
    while (cursor->next != NULL) cursor = cursor->next;
    cursor->next = line;
  }
  list->number_of_lines++;
}

// removes the first occurance of db_line from the list
void removeFromList(db_list *list, db_line *line)
{
  if (list == NULL) return;
  if (list->first == NULL) return;
 
  db_line *cursor = list->first;
  if (cursor == line)
  {
    // the head is the first instance, remove it.
    list->first = cursor->next;
    // do some action to clean up the memory from the first item.  This structure is pointed
    // to still by cursor.  If you do not, it will result in a memory leak of at least 8 bytes.
  }
  else
  {
    // track it down.
    do
    {
      if (cursor->next == line)
      {
        db_line *to_delete = cursor->next;
        cursor->next = cursor->next->next;
        // again, do something to clean up this memory to avoid a memory leak.
        // this time, the line to clean up is in to_delete.
        break;
      }
    } while (cursor->next != NULL);
  }
}


You're on your own for the rest.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

NicoQwertyu

Yes, I read your post.  I ignored the comment about std::vector because I'm using C (not C++), which I clearly stated in my post; guess you missed it.  Thanks for your help, thusfar though, I do appreciate it.  I'll go with malloc().  Thanks, guys.


Adron

Why store it in an array or vector if you are just rewriting it with one line removed? Read and write in parallell!


Adron


// Remove line 72 from a file
// Max line length 255 chars

FILE *in = fopen("infile", "rt"), *out = fopen("outfile", "wt");
char line[256];
int lineno = 0;

while(fgets(line, 256, in))
  if(++lineno != 72)
    fputs(line, out);

shout

If you are using malloc(), remember to use free()!

nslay

Quote from: Adron on October 04, 2005, 09:29 AM

// Remove line 72 from a file
// Max line length 255 chars

FILE *in = fopen("infile", "rt"), *out = fopen("outfile", "wt");
char line[256];
int lineno = 0;

while(fgets(line, 256, in))
  if(++lineno != 72)
    fputs(line, out);


On Linux and only Linux, you can use getline() instead of fgets() which is a GNU extension to stdio.h. 

getline man page