简体   繁体   中英

getline() infinite loop while reading from file

I'm trying to take text from file 1 and justify the content to file 2 by filling spaces with a random seed.

Everything seems to be working but I can't reach the end of the input file. The program get stuck in the loop when reading a certain line.

File 1 for reading

https://pastebin.com/raw/rRhcz3Tw

File 2 after pasting file 1

https://pastebin.com/raw/uRrJVdy3

I've read about flags problem and i'm wondering if that may be the case?

My code:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

unsigned int plusLongueChaine(ifstream& file);
void ajoutEspace(string& ligne, const unsigned int maxChaine);

int main()
{
    srand(time(0));

    // Création des instances de lecture et écriture
    ifstream fin("ip.txt", ios::in);
    ofstream fout("ip2.txt", ios::out);

    // Si le fichier n'est pas trouvé
    if (!fin.is_open()) {
        cerr << "Ouverture du fichier impossible." << endl;
        return 1; // Prototype dans cstdlib
    }

    // 1 - Trouver la plus longue ligne dans le fichier
    const unsigned int maxChaine = plusLongueChaine(fin);
    string ligneAEcrire;

    fin.clear();
    fin.seekg(0, ios::beg);
    

    // 2 - Boucle principale
    while (getline(fin, ligneAEcrire)) {
        if (ligneAEcrire.empty()) {
            fout << "\n" << endl;
            continue;
        }

        if (ligneAEcrire.size() < maxChaine)
            ajoutEspace(ligneAEcrire, maxChaine);


        fout << ligneAEcrire << endl;
    }

    cout << maxChaine; // 84


    return 0;
}

void ajoutEspace(string& ligne, const unsigned int maxChaine) {
    unsigned int position = 0;

    while (ligne.size() < maxChaine) {
        position = ligne.find(' ', position);

        if (position < ligne.size() && position != string::npos) {
            if (rand() & 1)
                ligne.insert(position, "_");

            position = ligne.find_first_not_of(' ', position);
            cout << position << endl; 
        }
        else {
            position = 0;
        }
    }

}

unsigned int plusLongueChaine(ifstream& file) {
    string ligne;
    unsigned int longueurChaine = 0;

    while (getline(file, ligne)) {
        if (ligne.size() > longueurChaine)
            longueurChaine = ligne.size();
    }

    return longueurChaine;
}

Your problem is in void ajoutEspace(string& ligne) which enters an infinite loop. You do not need to pass maxChaine as a parameter. You are passing a reference to a std::string line. All you want to do is find the ' ' in the line and convert to '_' in a varying manner. Simply use position = ligne.find(' ', position) and then update position += 1; (and another +1 if the space is randomly replaced with '_' ) before the next call, eg

void ajoutEspace(string& ligne)
{
    size_t position = 0;

    while ((position = ligne.find(' ', position)) != std::string::npos) {
            if (rand() & 1) {
                ligne.insert(position, "_");
                position += 1;
            }
            position += 1;
    }
}

( note: the change to size_t from unsigned int . You should be receiving warnings about your tests always being true when you compare, eg position:= string::npos due to the limitation of the range of unsigned int compared to size_t )

You are using find , so control your loop based on the return from find() , eg

    while ((position = ligne.find(' ', position)) != std::string::npos) {

That way you ensure you break the loop the first time a space is not found.

Example Output File

First ten lines of the modified file:

$ head ip2.txt
1. Introduction


1.1. Motivation


Le Protocole_ Internet est conçu pour_ supporter l'intercommunication_ de systèmes_
informatiques sur une base_ de_ réseau_ par_ commutation de paquets. Un_ tel_ système_ est
appelé "catenet"_ [1]. Le rôle du protocole_ Internet est_ la_ transmission de blocs de
données,_ appelés_ datagrammes,_ d'une_ source_ vers une destination, la_ source_ et la

( note: your line fout << "\n" << endl; inserts two newlines for every empty line in the original file)

Make the changes and let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM