streng - Slet tomme linjer fra en tekstfil i C ++

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har en tekstfil, som kan indeholde nogle tomme linjer. Jeg vil åbne denne fil og kigge efter de tomme linjer. Hvis der findes en tom linje, så vil jeg slette den linje. Jeg vil ikke oprette en midlertidig fil til dette formål. Jeg vil redigere den samme fil og lukke den efterfølgende.


Jeg har allerede set et par indlæg om lignende problem, men ingen af ​​dem arbejdede for mig.


void DeleteEmptyLines(const string& FilePath)
{
    //EXISTING File
    std::fstream FileStream;
    std::string CurrentReadLine;
    if (doesFileExist(FilePath))
    {
        FileStream.open(FilePath, std::fstream::in | std::fstream::out | std::fstream::app);

        //Read all the lines till the end of the file
        while(getline(FileStream, CurrentReadLine))
        {
            //Check if the line is empty
            if(CurrentReadLine.empty())
            {
                cout<<"Empty line found"<<endl;
                //DELETE THIS EMPTY LINE
            }
        }

        FileStream.clear();
        FileStream.close();
    }
    // else --->> do nothing
}


Aktuel fil (MyFile.txt):


Line1

Line2

Line3


Hvad jeg har brug for (MyFile.txt):


Line1
Line2
Line3


PS: Jeg bruger VS2010 på Windows-maskine.

Bedste reference


Enkel løsning. Læser filen i en string springende tomme linjer, overskriver derefter filen med indholdet af string.


void DeleteEmptyLines(const std::string &FilePath)
{
    std::ifstream in(FilePath);
    std::string line, text;
    while (std::getline(in, line))
        if !(line.empty() || line.find\_first\_not\_of(' ') == std::string::npos)
            text += line + "
"
    in.close();
    std::ofstream out(FilePath);
    out << text;
}


EDIT: @skm Det nye svar, du har indsendt, sletter ikke linjer med tomme mellemrum, som du sagde.


For at løse dette skal du bruge denne betingelse for at sikre, at en linje ikke er 'tom':


!(CurrentReadLine.empty() || CurrentReadLine.find\_first\_not\_of(' ') == std::string::npos)

Andre referencer 1


Du kan ikke gøre det i alle aktuelt anvendte filsystemer, fordi data gemmes successivt. Så 'slet' nogle bytes fra fil, du er nødt til at flytte alle efterfølgende bytes ved den mængde bytes. Og du kan ikke åbne filen til læsning og genskriv det på det tidspunkt fra begyndelsen.


Så du har 3 muligheder:



  1. Læs hele filen i hukommelsen, og skriv om linjerne til originalen
    fil overspringer tomme linjer.

  2. Læs fil linje for linje, gem kun
    ikke-tomme linjer i hukommelsen, og skriv derefter ned til den samme fil.

  3. Brug midlertidig fil, hvilket faktisk er et godt valg, fordi du
    behøver ikke have en masse RAM og fil flytning operation er
    billigst ved de fleste filsystemer (hvis kilde og destination er på
    samme partition).


Andre referencer 2


Jeg har ændret min funktion som følgende.


void DeleteEmptyLines(const string& FilePath)
{
    std::string BufferString = "";

    //File
    std::fstream FileStream;
    std::string CurrentReadLine;
    if (doesFileExist(FilePath))
    {
        FileStream.open(FilePath, std::fstream::in); //open the file in Input mode

        //Read all the lines till the end of the file
        while(getline(FileStream, CurrentReadLine))
        {   
            //Check if the line is empty
            if(!CurrentReadLine.empty())
                BufferString = BufferString + CurrentReadLine + "
";   
        }
        if(DEBUG) cout<<BufferString<<endl;
        FileStream.close();

        FileStream.open(FilePath, std::fstream::out); //open file in Output mode. This line will delete all data inside the file.
        FileStream << BufferString;
        FileStream.close();
    }
    // else --->> do nothing
}


Denne funktion gør følgende trin:



  1. Åbn filen i input-tilstand

  2. Læs alle de linjer, der ikke er tomme

  3. Luk filen

  4. Åbn filen igen i Output-tilstand (sletter al data inde i filen)

  5. Sæt strengen i filen

  6. Luk filen.