【问题标题】:getline() infinite loop while reading from file从文件读取时getline()无限循环
【发布时间】:2021-06-27 19:16:46
【问题描述】:

我正在尝试从文件 1 中获取文本,并通过用随机种子填充空格来证明文件 2 的内容。

似乎一切正常,但我无法到达输入文件的末尾。程序在读取某行时卡在循环中。

文件 1 供阅读

https://pastebin.com/raw/rRhcz3Tw

粘贴文件 1 后的文件 2

https://pastebin.com/raw/uRrJVdy3

我已经阅读了有关标志问题的信息,我想知道是否可能是这种情况?

我的代码:

#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;
}

【问题讨论】:

    标签: c++ file iostream


    【解决方案1】:

    您的问题出在void ajoutEspace(string&amp; ligne) 中,它进入了无限循环。您不需要将maxChaine 作为参数传递。您正在传递对 std::string 行的引用。您要做的就是在该行中找到' ' 并以不同的方式转换为'_'。只需使用position = ligne.find(' ', position),然后在下一次调用之前更新position += 1;(如果空格随机替换为'_',则更新另一个+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;
        }
    }
    

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

    你正在使用find,所以根据find()的返回来控制你的循环,例如

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

    这样可以确保在第一次找不到空格时就中断循环。

    示例输出文件

    修改后文件的前十行:

    $ 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
    

    注意:您的行 fout &lt;&lt; "\n" &lt;&lt; endl; 为原始文件中的每个空行插入两个换行符)

    进行更改,如果您还有其他问题,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多