简体   繁体   English

从文件读取时getline()无限循环

[英]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.我正在尝试从文件 1 中获取文本,并通过用随机种子填充空格来证明文件 2 的内容。

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文件 1 供阅读

https://pastebin.com/raw/rRhcz3Tw https://pastebin.com/raw/rRhcz3Tw

File 2 after pasting file 1粘贴文件 1 后的文件 2

https://pastebin.com/raw/uRrJVdy3 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.您的问题出在进入无限循环的void ajoutEspace(string& ligne)中。 You do not need to pass maxChaine as a parameter.您不需要将maxChaine作为参数传递。 You are passing a reference to a std::string line.您正在传递对std::string行的引用。 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;只需使用position = ligne.find(' ', position)然后更新position += 1; (and another +1 if the space is randomly replaced with '_' ) before the next call, eg (如果空格被随机替换为另一个+1 '_' )在下一次调用之前,例如

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 ) 注意:unsigned int更改为size_t 。当您比较时,您应该会收到有关您的测试始终为true警告,例如position:= string::npos由于unsigned intsize_t相比范围的限制)

You are using find , so control your loop based on the return from find() , eg您正在使用find ,因此根据find()的返回控制您的循环,例如

    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示例 Output 文件

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) 注意:你的 line fout << "\n" << endl;为原始文件中的每个空行插入两个换行符)

Make the changes and let me know if you have further questions.进行更改,如果您还有其他问题,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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