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

getline() infinite loop while reading from file

提问人:uwponcel 提问时间:4/1/2021 更新时间:4/1/2021 访问量:270

问:

我正在尝试从文件 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++ 文件 IOSTREAM

评论


答:

0赞 David C. Rankin 4/1/2021 #1

你的问题是进入一个无限循环。您不需要作为参数传递。您正在传递对行的引用。您要做的就是找到行中的 并以不同的方式转换为。只需在下一次调用之前使用然后更新(如果空格被随机替换为),则再更新一次,例如void ajoutEspace(string& ligne)maxChainestd::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;
    }
}

(注意:更改为 从 .您应该总是在比较时收到有关测试的警告,例如 由于范围的限制,与size_tunsigned inttrueposition != string::nposunsigned intsize_t)

您正在使用 ,因此根据 返回 来控制您的循环,例如findfind()

    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 << "\n" << endl;

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