Функция getline () не работает в цикле while - PullRequest
0 голосов
/ 19 марта 2019

Я хочу сделать простую программу ввода-вывода файлов с внешним классом «File_Opening_and_Closing.cpp», когда я использую функцию «getline ()» без цикла , она работает нормально, но когда я использую »getline () »Функция с циклом do while в« main.cpp »сбивает.

Скажите, пожалуйста, где проблема и как ее решить?

main.cpp

    #include<iostream>
    #include<fstream>
    #include "File_Opening_and_Closing.h" using namespace std;

    int main() {
        int i=1;
        char file_make='y';
        char file_insert='y';

        do
        {
            File_Opening_and_Closing file[i];

            do
            {
                file[i].put_data();
                file[i].show_data();
                cout<<"Do you want to insert text again ? 'y' OR 'n'"<<endl;
                cin>>file_insert;
            }while(file_make=='y');
            i++;
            cout<<"Do you want to Make another file ? 'y' OR 'n'"<<endl;
            cin>>file_make;
        }while(file_insert=='y');

return 0;}

без петли, работающей нормально >>

 int main() {
            File_Opening_and_Closing file;
            file.put_data();
            file.show_data();
 return 0;}

File_Opening_and_Closing.cpp

#include "File_Opening_and_Closing.h"

File_Opening_and_Closing::File_Opening_and_Closing()
{
    cout<<"Enter the file name and type => ";
    cin>>file_name;
}

void File_Opening_and_Closing::put_data(){
    ofstream file_out;
    file_out.open(file_name);

    cin.ignore();
    cout<<"Enter the string => ";
    cin.ignore();

//  getline is not working here!

    getline(cin,data);

    data = "Hello World!";

    file_out<<data;
    file_out.close();
}

void File_Opening_and_Closing::show_data(){
    ifstream file_in;

    file_in.open(file_name);

    getline(file_in,data);
    cout<<data;

    file_in.close();
}

File_Opening_and_Closing.h

#ifndef FILE_OPENING_AND_CLOSING_H
#define FILE_OPENING_AND_CLOSING_H
#include<iostream>
#include<fstream>
using namespace std;


class File_Opening_and_Closing
{
    private:
        string file_name;
        string data;
    public:
        File_Opening_and_Closing();
        void put_data();
        void show_data();
    protected:
};

#endif // FILE_OPENING_AND_CLOSING_H

Проблемное изображение

1 Ответ

1 голос
/ 19 марта 2019

У вас есть целый ряд проблем, не в последнюю очередь из того, что является Как отлаживать небольшие программы проблема, в которой вы перепутали используемые переменные для проверки обоих do .. while (...); циклов, например

            ...
            cin>>file_insert;
        }while(file_make=='y');
        // i++; (not needed and VLA's not allowed in C++
        cout<<"Do you want to Make another file ? 'y' OR 'n'"<<endl;
        cin>>file_make;
    }while(file_insert=='y');

Во-вторых, как уже упоминалось в комментариях, Стандарт C ++ не допускает Массивы переменной длины .

    File_Opening_and_Closing file[i];

Если вам нужно более 1 экземпляра вашего класса, используйте вектор классов или массив классов. Однако в вашем коде нет необходимости ни для того, ни для другого. Поскольку вы создаете новый экземпляр File_Opening_and_Closing на каждой итерации цикла do { ... } while (..);, вы можете просто использовать:

    File_Opening_and_Closing file;

Вы делаете вещи невероятно тяжелыми для себя , объявляя file_make и file_insert типом char. Вместо этого просто сделайте их std::string и протестируйте, например, с помощью if (file_make == "y"). Это позволит вам читать весь ввод с getline, избегая проблем со смешанным использованием std::cin и getline.

Остальные проблемы - полная ошибка проверки открытий файлов, например, if (!file_out.is_open()) { /* handle error */ } с аналогичными тестами, необходимыми для каждого ввода, чтобы гарантировать, что вы можете перехватить отмену ввода пользователем, генерирующим руководство EOF с помощью Ctrl + d (или Ctrl + z в окнах ).

Кроме того, не помещайте using namespace std; в заголовочные файлы. Нет необходимости вставлять стандартное пространство имен в каждый файл, использующий ваш заголовок (хотя вы хорошо поработали и защитили от множественных включений с помощью средств защиты заголовков FILE_OPENING_AND_CLOSING_H). На самом деле здесь нет никаких оснований для using namespace std;. Просто используйте std:: оператор разрешения пространства имен для cin, cout и т. Д.

Оставляя проверки для добавления, решая другие проблемы, вы можете сделать что-то похожее на:

File_Opening_and_Closing.h

#ifndef FILE_OPENING_AND_CLOSING_H
#define FILE_OPENING_AND_CLOSING_H

#include<iostream>
#include<fstream>

class File_Opening_and_Closing
{
    private:
        std::string file_name;
        std::string data;
    public:
        File_Opening_and_Closing();
        void put_data();
        void show_data();
    protected:
};

#endif

File_Opening_and_Closing.cpp

#include "File_Opening_and_Closing.h"

File_Opening_and_Closing::File_Opening_and_Closing()
{
    std::cout << "Enter the file name and type => ";
    getline (std::cin, file_name);
}

void File_Opening_and_Closing::put_data(){
    std::ofstream file_out;
    file_out.open(file_name);

    std::cout<<"Enter the string => ";

    getline (std::cin, data);


    file_out << data << '\n';
    file_out.close();
}

void File_Opening_and_Closing::show_data(){
    std::ifstream file_in;

    file_in.open (file_name);

    getline (file_in,data);
    std::cout << data << '\n';

    file_in.close();
}

main.cpp

#include<iostream>
#include<fstream>

#include "File_Opening_and_Closing.h"

int main (void) {

    std::string file_make = "y";
    std::string file_insert = "y";

    do
    {
        File_Opening_and_Closing file;

        do
        {
            file.put_data();
            file.show_data();
            std::cout << "Do you want to insert text again ? 'y' OR 'n'\n";
            getline (std::cin, file_insert);
        } while (file_insert == "y");
        std::cout << "Do you want to Make another file ? 'y' OR 'n'\n";
        getline (std::cin, file_make);
    } while (file_make == "y");

    return 0;
}

Теперь он будет создавать столько файлов, сколько вам нужно (хотя вы захотите заглянуть в режим std::ios::app, если хотите добавить более одной строки.

Пример использования / Вывод

$ ./bin/main
Enter the file name and type => out1
Enter the string => foobar
foobar
Do you want to insert text again ? 'y' OR 'n'
y
Enter the string => barbaz
barbaz
Do you want to insert text again ? 'y' OR 'n'
n
Do you want to Make another file ? 'y' OR 'n'
y
Enter the file name and type => out2
Enter the string => bazbuz
bazbuz
Do you want to insert text again ? 'y' OR 'n'
n
Do you want to Make another file ? 'y' OR 'n'
n

Результирующие выходные файлы

$ cat out1
barbaz

$ cat out2
bazbuz

Дайте мне знать, если у вас есть дополнительные вопросы.

...