2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 C++: запись и чтение файла в текстовом редакторе
Сообщение20.01.2016, 11:28 
Здравствуйте, я осваиваю "С++" по книге Страуструпа "Программирование. принципы и практика использования С++". Я внес изменения в пример книги, чтобы программа - текстовой редактор записывала текст на диск и читала с него, - программа создаёт файл но не записывает в него ничего. Не могли бы Вы подсказать что я неправильно сделал.
Вот код:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
//
// This is example code from Chapter 20.6.1 "Lines" of
// "Programming -- Principles and Practice Using C++" by Bjarne Stroustrup
//

#include "std_lib_facilities.h"

//------------------------------------------------------------------------------
typedef vector<char> Line;    // a line is a vector of characters

//------------------------------------------------------------------------------

struct Document {
    list<Line> line;    // a document is a list of lines
    Document() { line.push_back(Line()); }
};

//------------------------------------------------------------------------------


ofstream& operator<<(ofstream& ost, Document& d)
{
    char ch(0);
    while (ost<<ch)
                ost.put(ch);    // add the character
       
   
    return ost<<d
                ;
}



//istream& operator>>(istream& is, Document& d)
//{
  //  char ch;
   // while (is>>ch) {
     //   d.line.back().push_back(ch);    // add the character
       // if (ch=='\n') {
         //   d.line.push_back(Line());   // add another line
        //}
    //}
    //return is;
//}

istream& operator>>(istream& cin, Document& d)
{
    char ch;
    while (cin>>ch) {
        d.line.back().push_back(ch);    // add the character
        if (ch=='\n') {
            d.line.push_back(Line());   // add another line
        }
    }
    return cin;
}

//------------------------------------------------------------------------------

int main()
{
    Document d;
    {
       
        std::ofstream ost("Dokument", ios_base::app);
        cin >> d;
        if(!ost)
        cerr<<"File error";
        else
        {
                while (cin!=0) {ost<<d<<endl<<"proba";} ost.close();}
};
}

//------------------------------------------------------------------------------
 

 
 
 
 Re: Текстовый редактор
Сообщение20.01.2016, 13:36 
Аватара пользователя
Поясните, пожалуйста, что должна делать функция:
Используется синтаксис C++
ofstream& operator<<(ofstream& ost, Document& d)
{
    char ch(0);
    while (ost<<ch)
                ost.put(ch);    // add the character
       
   
    return ost<<d
                ;
}
:?:
И что она делает на самом деле? В частности, что делает цикл while (ost<<ch) ost.put(ch);? И чем отличается ost<<ch от ost.put(ch)? И что выполняет инструкция return ost<<d?

Также, пожалуйста, поясните при каких условиях происходит выход из функции:
Используется синтаксис C++
istream& operator>>(istream& cin, Document& d)
{
    char ch;
    while (cin>>ch) {
        d.line.back().push_back(ch);    // add the character
        if (ch=='\n') {
            d.line.push_back(Line());   // add another line
        }
    }
    return cin;
}
:?:
Конкретно, выход из цикла while (cin>>ch) {. . .} при каких условиях происходит?

-- 20 янв 2016, 13:42 --

(непонятка)

И какой был смысл в изменении оригинального имени переменной is на cin? Это, по меньшей мере, некрасиво и чревато тонкими ошибками.

В чём смысл цикла while (cin!=0) {ost<<d<<endl<<"proba";}? Он, вообще, сработает?

 
 
 
 Re: Текстовый редактор
Сообщение20.01.2016, 16:32 
Функция ofstream& operator<<(ofstream& ost, Document& d) это переопределение оператора вывода "<<" для типа Document.
while (ost<<ch) ost.put(ch) - означает, выводить символы, пока они есть в наличии;
"ost<<ch" - это запись логического выражения, которое истинно, пока есть в потоке символы, а ost.put(ch) - это операция добавления символов в поток стандартный вывода, т. е. то, ради чего и происходило переопределение стандартного оператора вывода "<<" для типа Document ("С++" не знает как вывести тип Document и ему это "объясняется" при переопределении).
В функции istream& operator>>(istream& cin, Document& d) выход происходит, когда в потоке ввода заканчиваются символы.
Цикл while (cin!=0) {ost<<d<<endl<<"proba";} был введен в программу Страуструпом и модифицирован мной в целях поиска ошибки, - когда была обнаружена проблема - незапись данных в файл и был попыткой проверить, выводится ли в файл хоть что то, в данном случае - слово "proba". Он не сработал и это даёт некоторую подсказку, вероятно, почему то как раз cin=0 и никогда не становилось ненулевым.

 
 
 
 Re: Текстовый редактор
Сообщение20.01.2016, 17:33 
Аватара пользователя
Vjatcheslav1 в сообщении #1092613 писал(а):
Функция ofstream& operator<<(ofstream& ost, Document& d) это переопределение оператора вывода "<<" для типа Document.
А что она делает на самом деле?

Vjatcheslav1 в сообщении #1092613 писал(а):
while (ost<<ch) ost.put(ch) - означает, выводить символы, пока они есть в наличии;
Нет, это означает — попытаться вывести символ ch в поток ost и если получилось, то снова вывести его в поток, затем вернуться в начало цикла. Думаю это не то, что вы хотели.

Vjatcheslav1 в сообщении #1092613 писал(а):
"ost<<ch" - это запись логического выражения, которое истинно, пока есть в потоке символы
Это вставка символа ch в поток ost, кроме того это выражение возвращает состояние поток ost, которое равно true если операция вставки выполнима.

Vjatcheslav1 в сообщении #1092613 писал(а):
ost.put(ch) - это операция добавления символов в поток стандартный вывода
Фактически это синоним ost<<ch (ну почти синоним), так что вы дважды вставляете один символ в поток.

А чтобы ваша функция работала так как вы хотите её можно, например, определить так:
Используется синтаксис C++
ostream& operator<<(ostream& ost, Document& d){
        for(list<Line>::iterator p = d.line.begin(); p != d.line.end(); p++)
                for(Line::iterator q = p->begin(); q != p->end(); q++)
                        ost.put(*q);
        return ost;
}

Vjatcheslav1 в сообщении #1092613 писал(а):
В функции istream& operator>>(istream& cin, Document& d) выход происходит, когда в потоке ввода заканчиваются символы.
Поток ввода cin получает значение false при вводе специального символа Ctrl+Z в новой строке (либо нажатии функциональной клавиши F6), ибо в потоке cin символы сами по себе никогда не заканчиваются.

Vjatcheslav1 в сообщении #1092613 писал(а):
Цикл while (cin!=0) {ost<<d<<endl<<"proba";} был введен в программу Страуструпом и модифицирован мной в целях поиска ошибки, - когда была обнаружена проблема - незапись данных в файл и был попыткой проверить, выводится ли в файл хоть что то, в данном случае - слово "proba". Он не сработал и это даёт некоторую подсказку, вероятно, почему то как раз cin=0 и никогда не становилось ненулевым
Видимо вы очень вольно модифицировали код Струструпа. Это очень грубая ошибка. Лучше напишите так, например:
Используется синтаксис C++
int main(){
    ofstream ost("Dokument.txt", ios::app);
    if(!ost) cerr << "File error\n";
    else{
        Document d;
        cin >> d;
        ost << d << endl;
    }
}

 
 
 
 Re: Текстовый редактор
Сообщение21.01.2016, 09:06 
Спасибо за помощь, - следуя этим советам я еще раз попытаюсь исправить ошибки. Если не получится, - вновь напишу в тему.
Я подумал ещё и мне пришла вот такая мысль: символы не попадают в выходной поток потому что я не доработал функцию ofstream& operator<<(ofstream& ost, Document& d).
Вот её код в моей версии:
Используется синтаксис C++
ofstream& operator<<(ofstream& ost, Document& d)
{
    char ch(0);
    while (ost<<ch)
                ost.put(ch);    // add the character
       
   
    return ost<<d
                ;
}


Здесь видно, что символы из d никак не попадают в переменную ch и, значит, не могут попасть в выходной поток и из него - файл. Попробую её доработать.
Для сравнения, вот здесь запись символа из потока в переменную прописана:
Используется синтаксис C++
istream& operator>>(istream& cin, Document& d)
{
    char ch;
    while (cin>>ch) {
        d.line.back().push_back(ch);    // add the character
        if (ch=='\n') {
            d.line.push_back(Line());   // add another line
        }
    }
    return cin;
}

 
 
 
 Re: Текстовый редактор
Сообщение21.01.2016, 10:29 
Аватара пользователя

(бурчание под нос)

И всё же я считаю, что изменение имени формального параметра is на cin было плохой идеей. Да и is.get(ch) лучше было оставить, а не менять на cin>>ch. Впрочем, и с вашими изменениями функция istream& operator>>(istream& cin, Document& d) будет работать.

Подозреваю, что вы хотели чтобы ваша функция работала именно со стандартным потоком ввода cin, но этого не получилось и ваша редакция практически эквивалентна определению Стауструпа, а потому и работает. :-)

 
 
 
 Re: C++: запись и чтение файла в текстовом редакторе
Сообщение22.01.2016, 01:23 
Аватара пользователя
 i  Отделено от темы «Текстовый редактор»

 
 
 [ Сообщений: 7 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group