Valhalla Legends Forums Archive | C/C++ Programming | File Manipulation

AuthorMessageTime
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?
October 3, 2005, 5:58 PM
Myndfyr
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).
October 3, 2005, 6:03 PM
NicoQwertyu
How am I suppost to make an char array without a... uh... hardcoded size?
October 3, 2005, 6:16 PM
shout
void *malloc(size_t length)
October 3, 2005, 9:49 PM
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.
October 3, 2005, 11:58 PM
Myndfyr
[quote author=NicoQwertyu link=topic=12954.msg129897#msg129897 date=1128363392]
How am I suppost to make an char array without a... uh... hardcoded size?
[/quote]

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:

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

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.
[code]
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);
  }
}
[/code]

You're on your own for the rest.
October 4, 2005, 12:13 AM
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.
October 4, 2005, 1:36 AM
NicoQwertyu
Malloc is working beautifully.  Thanks for all your help.  :)
October 4, 2005, 2:19 AM
Adron
Why store it in an array or vector if you are just rewriting it with one line removed? Read and write in parallell!
October 4, 2005, 4:07 AM
NicoQwertyu
How do you mean?  :o
October 4, 2005, 11:24 AM
Adron
[code]
// 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);
[/code]
October 4, 2005, 2:29 PM
shout
If you are using malloc(), remember to use free()!
October 4, 2005, 6:47 PM
nslay
[quote author=Adron link=topic=12954.msg129948#msg129948 date=1128436165]
[code]
// 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);
[/code]
[/quote]

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

getline man page
October 5, 2005, 11:44 AM

Search