2014 dxdy logo

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

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




Начать новую тему Ответить на тему
 
 с++ ubuntu открытие файла
Сообщение18.04.2016, 20:14 
Аватара пользователя


26/03/13
326
Russia
Переделал в программе обработку ошибок пользователя на исключения:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <fstream>// для файловых потоков
#include <iostream>
#include <cstdlib>// для exit()
using namespace std;
using std::ios;
const int MAX = 1000;
int buff[MAX];
//////////////////////////////////////////////
class dofile{
        private:
                char* name;
                fstream file;
        public:
                class unable_to_open{};
                class unable_to_write{};
                class unable_to_read{};
                dofile(){}
                dofile(char* nm):name(nm){}
                void open_trunc(){
                        file.open(name,ios::trunc|ios::binary);
                        if(!file)throw unable_to_open();
                }
                void open_add(){
                        file.open(name,ios::ate|ios::binary);
                        if(!file)throw unable_to_open();
                }
                void close(){file.close();}
                void write(int buffer[],int numb_of_obj){
                        file.write(reinterpret_cast<char*>(buffer),numb_of_obj*sizeof(int));
                        if(!file)throw unable_to_write();
                }
                void read(int buffer[],int numb_of_obj){
                        file.read(reinterpret_cast<char*>(buffer),numb_of_obj*sizeof(int));
                        if(!file)throw unable_to_read();
                }


};
////////////////////////////////////////////////
int main(){
        try{
        for(int j = 0; j < MAX; j++)// заполнить буфер данными
                buff[j] = j;
        dofile file("ex12.txt");
        file.open_trunc();
        //ofstream os; // создать выходной поток
        //os.open("a:edata.dat", ios::trunc | ios::binary); // открыть его
        //if(!os){cerr << "Невозможно открыть выходной файл\n";exit(1);}
       
        cout << "Идет запись...\n";
        file.write(buff,MAX);
        //os.write(reinterpret_cast<char*>(buff), MAX*sizeof(int));// записать в него содержимое буфера
        //if(!os){ cerr << "Запись в файл невозможна\n"; exit(1); }
        //file.close();// надо закрыть поток

        for(int j = 0; j < MAX; j++)
                buff[j] = 0;// очистить буфер

        //ifstream is;// создать входной поток
        //is.open("a:edata.dat", ios::binary);
        //if(!is){ cerr << "Невозможно открыть входной файл\n";exit(1); }
        cout << "Идет чтение...\n"; // чтение файла
        file.read(buff,MAX);
        //is.read(reinterpret_cast<char*>(buff), MAX*sizeof(int));
        //if(!is){ cerr << "Невозможно чтение файла\n"; exit(1); }
        for(int j = 0; j < MAX; j++)// проверять данные
                if(buff[j] != j){ cerr << "\nДанные некорректны\n"; exit(1); }
        cout << "Данные в порядке\n";
        }
        catch(dofile::unable_to_open){cout<<"Unable to open a file..."<<endl;}
        catch(dofile::unable_to_write){cout<<"Unable to write a file..."<<endl;}
        catch(dofile::unable_to_read){cout<<"Unable to read a file..."<<endl;}
return 0;
}
 


При этом сразу срабатывает исключение о невозможности открытия файла

http://postimg.org/image/c3w1jq189/

Я так понимаю, что есть проблема с названием файла

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение18.04.2016, 20:34 
Заслуженный участник


04/05/09
4582
Я точно не помню, но, возможно, надо указать доступ на чтение/запись в open():
Используется синтаксис C++
  file.open(name,ios::in|ios::out|ios::trunc|ios::binary);

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение18.04.2016, 20:51 


27/08/14
206
Ещё, если Вы хотите прочитать то, что записали, необходимо перевести позицию чтения на начало:
Используется синтаксис C++
file.seekg(ios::beg);

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение18.04.2016, 23:24 
Аватара пользователя


26/03/13
326
Russia
Спасибо! Работает:

код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include <fstream>// для файловых потоков
#include <iostream>
#include <cstdlib>// для exit()
using namespace std;
using std::ios;
const int MAX = 1000;
int buff[MAX];
//////////////////////////////////////////////
class dofile{
        private:
                char* name;
                fstream file;
        public:
                class unable_to_open{};
                class unable_to_write{};
                class unable_to_read{};
                dofile(){}
                dofile(char* nm):name(nm){}
                void open_trunc(){
                        file.open(name,ios::trunc|ios::binary|ios::in|ios::out);
                        if(!file)throw unable_to_open();
                }
                void open_add(){
                        file.open(name,ios::ate|ios::binary|ios::in|ios::out);
                        if(!file)throw unable_to_open();
                }
                void close(){file.close();}
                void write(int buffer[],int numb_of_obj){
                        file.write(reinterpret_cast<char*>(buffer),numb_of_obj*sizeof(int));
                        if(!file)throw unable_to_write();
                }
                void read(int buffer[],int numb_of_obj){
                        file.read(reinterpret_cast<char*>(buffer),numb_of_obj*sizeof(int));
                        if(!file)throw unable_to_read();
                }
                void move_flag(){file.seekg(ios::beg);}
};
////////////////////////////////////////////////
int main(){
        try{
        for(int j = 0; j < MAX; j++)// заполнить буфер данными
                buff[j] = j;
        dofile file("ex12.txt");
        file.open_trunc();
        //ofstream os; // создать выходной поток
        //os.open("a:edata.dat", ios::trunc | ios::binary); // открыть его
        //if(!os){cerr << "Невозможно открыть выходной файл\n";exit(1);}
       
        cout << "Идет запись...\n";
        file.write(buff,MAX);
        //os.write(reinterpret_cast<char*>(buff), MAX*sizeof(int));// записать в него содержимое буфера
        //if(!os){ cerr << "Запись в файл невозможна\n"; exit(1); }
        //file.close();// надо закрыть поток

        for(int j = 0; j < MAX; j++)
                buff[j] = 0;// очистить буфер

        //ifstream is;// создать входной поток
        //is.open("a:edata.dat", ios::binary);
        //if(!is){ cerr << "Невозможно открыть входной файл\n";exit(1); }
        cout << "Идет чтение...\n"; // чтение файла
        file.move_flag();
        file.read(buff,MAX);
        //is.read(reinterpret_cast<char*>(buff), MAX*sizeof(int));
        //if(!is){ cerr << "Невозможно чтение файла\n"; exit(1); }
        for(int j = 0; j < MAX; j++)// проверять данные
                if(buff[j] != j){ cerr << "\nДанные некорректны\n"; exit(1); }
        cout << "Данные в порядке\n";
        }
        catch(dofile::unable_to_open){cout<<"Unable to open a file..."<<endl;}
        catch(dofile::unable_to_write){cout<<"Unable to write a file..."<<endl;}
        catch(dofile::unable_to_read){cout<<"Unable to read a file..."<<endl;}
return 0;
}
 


Вроде у данного потокового объекта есть два флага: для чтения и записи. Почему нужно двигать флаг для чтения после записи?

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 01:00 
Аватара пользователя


28/01/12
467
Joe Black в сообщении #1116483 писал(а):
Вроде у данного потокового объекта есть два флага: для чтения и записи. Почему нужно двигать флаг для чтения после записи?
Вы что-то не так поняли?

Во-первых флаги чтения/записи относятся к тому - какие операции будут над файлом производиться и декларируются эти флаги в момент открытия файлов.
Если флага чтение (ios::in) - то разрешены операции чтения, записать с таким флагом открытый файл ничего не сможете.
Eсли флага записи(ios::out) - то файл предназначен только для записи.
Если как у вас (ios::in|ios::out) - то разрешены на файле операции и чтения и записи.

Во-вторых - вам посоветовали после операции записи перевести текущую позицию открытого файла на начало, что вы и сделали в методе void move_flag(), которую вы и вызвали после операции записи перед началом чтения.
Imho: Правильней было бы назвать эту методу - void move_position().

arseniiv - ok

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 01:40 
Заслуженный участник


27/04/09
28128
Понятно, в чём проблема. Не надо было называть метод move_flag. Флаги — это булевы значения, в том числе отдельные биты целого числа и константы, равные числам с одним такими битом и остальными нулями. Позиция в потоке флагом не называется. Позиция, вроде бы, у потока всё-таки обычно одна. (Часто можно открыть одну область памяти или файл как несколько разных потоков, и тогда иногда можно читать и писать там в разных местах как угодно, хоть параллельно — а иногда на это есть ограничения).

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 09:51 
Аватара пользователя


26/03/13
326
Russia
Ясно, зачем тогда объекту класса fstream два метода seekp() и seekg()?

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 11:32 
Заслуженный участник


27/04/09
28128
См. http://stackoverflow.com/questions/15670359/fstream-seekg-seekp-and-write.

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 15:38 
Аватара пользователя


26/03/13
326
Russia
Ясно, то есть общая позиция для чтения и записи:

A joint file position is maintained for both the input sequence and the output sequence.

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 15:53 
Аватара пользователя


28/01/12
467
Ок, всё верно.
Для закрепления вот ссылка на класс fstream, что он и из чего наследует.

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 17:13 
Заслуженный участник


04/05/09
4582
Кстати:
Цитата:
Используется синтаксис C++
void move_flag(){file.seekg(ios::beg);}

Первый параметр seekg() и seekp() - это позиция, а тип смещения - опциональный второй параметр. Вам повезло, что ios::beg равен нулю.

 Профиль  
                  
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 18:02 


27/08/14
206
venco в сообщении #1116650 писал(а):
Первый параметр seekg() и seekp() - это позиция, а тип смещения - опциональный второй параметр. Вам повезло, что ios::beg равен нулю.
Это я насоветовал - пропустил первый параметр :oops:. (Далее следуют мечты о более строгом С++, где такая ошибка была бы невозможной...)

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group