Zannix
Zannix

Reputation: 1593

How to delete an empty line from text file in C++?

I've been learning programming for about a year now in college and I've learned some stuff along the way so I decided to make my very own "Host editor" program which basically edits your windows hosts file, lets you insert, remove and manage the URLs inside. :)

However, I've ran into problems when trying to delete a URL from the file. I'm not actually deleting it since I don't know how to do it, but I create a new empty text file and then copy all the lines except the one with the URL that I wish to delete. Sounds reasonable?

It appears, however, that I can't delete the URL without leaving inside a so-called "empty line". At least not with how I've coded it... I've tried everything and I really need your help.

But please, use "noob friendly" language with me here, I won't understand any complicated terms :)

Thank you, and here's my full code:

http://joggingbenefits.net/hcode.txt

and here's just the part of the code that I think is messing with me (delete URL function):

void del(int lin)  // line index
{
    FILE* fp=fopen("C:\\Windows\\System32\\drivers\\etc\\hosts","r+");
    FILE* fp1=fopen("C:\\Windows\\System32\\drivers\\etc\\hosts1","w");

    char str[200];
    int cnt=0;

    while(! feof(fp))
    {
        fgets(str,200,fp);


        if(str[0]=='#')
        {
            fputs(str,fp1);
        }
        else
        {
            if(cnt==lin)
            {               // problem. FLAG?!
                cnt++;
            }
            else
            {
                    cnt++;
                    fputs(str,fp1);
            }

        }

    }



    fclose(fp);
    fclose(fp1);

    rename("C:\\Windows\\System32\\drivers\\etc\\hosts","C:\\Windows\\System32\\drivers\\etc\\deleteme");
    rename("C:\\Windows\\System32\\drivers\\etc\\hosts1","C:\\Windows\\System32\\drivers\\etc\\hosts");
    remove("C:\\Windows\\System32\\drivers\\etc\\deleteme");

    cout << endl << "LINE DELETED!" << endl;

}

Upvotes: 2

Views: 10809

Answers (3)

xaizek
xaizek

Reputation: 5252

Reason

fgets() function reads line including trailing end-of-line character ('\n'), while puts() function writes line passed to in and end-of-line character. So if you read

this line

it's stored as

this line\n

in str. And is written back to the file as

this line\n\n

which looks like this

this line

in the file.

Fix

  • Use fprintf(fp2, "%s", str);
  • Remove trailing "\n" in str before using fputs().

Upvotes: 0

Beta
Beta

Reputation: 99094

You haven't said how this code fails (or given us some text as an example), but I notice a problem with your loop. The "end of file" condition is caused by the act of trying to read past the end of the file, but you do the test (feof) before the fgets, so you operate on the last line twice: control enters the loop after the last line is read, tries -- and fails -- to read another line, acts on the line still in str, and then terminates the loop.

Instead of

while(! feof(fp))
  {
    fgets(str,200,fp))
    ...

try:

while(fgets(str,200,fp))
{
  ...

Upvotes: 0

Potatoswatter
Potatoswatter

Reputation: 137770

Since you have tagged this as C++, I'll assume that you want to rewrite it to eliminate the C FILE interface.

std::ifstream in_file("C:\\Windows\\System32\\drivers\\etc\\hosts");
std::ofstream out_file("C:\\Windows\\System32\\drivers\\etc\\hosts1");

std::string line;
while ( getline( in_file, line ) ) {
    if ( ! line.empty() ) {
        out_file << line << '\n';
    }
}

http://ideone.com/ZibDT

Very straightforward!

Upvotes: 4

Related Questions