2014 dxdy logo

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

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




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

код: [ скачать ] [ спрятать ]
Используется синтаксис 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 
Я точно не помню, но, возможно, надо указать доступ на чтение/запись в open():
Используется синтаксис C++
  file.open(name,ios::in|ios::out|ios::trunc|ios::binary);

 
 
 
 Re: с++ ubuntu открытие файла
Сообщение18.04.2016, 20:51 
Ещё, если Вы хотите прочитать то, что записали, необходимо перевести позицию чтения на начало:
Используется синтаксис C++
file.seekg(ios::beg);

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

код: [ скачать ] [ спрятать ]
Используется синтаксис 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 
Аватара пользователя
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 
Понятно, в чём проблема. Не надо было называть метод move_flag. Флаги — это булевы значения, в том числе отдельные биты целого числа и константы, равные числам с одним такими битом и остальными нулями. Позиция в потоке флагом не называется. Позиция, вроде бы, у потока всё-таки обычно одна. (Часто можно открыть одну область памяти или файл как несколько разных потоков, и тогда иногда можно читать и писать там в разных местах как угодно, хоть параллельно — а иногда на это есть ограничения).

 
 
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 09:51 
Аватара пользователя
Ясно, зачем тогда объекту класса fstream два метода seekp() и seekg()?

 
 
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 11:32 
См. http://stackoverflow.com/questions/15670359/fstream-seekg-seekp-and-write.

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

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

 
 
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 15:53 
Аватара пользователя
Ок, всё верно.
Для закрепления вот ссылка на класс fstream, что он и из чего наследует.

 
 
 
 Re: с++ ubuntu открытие файла
Сообщение19.04.2016, 17:13 
Кстати:
Цитата:
Используется синтаксис C++
void move_flag(){file.seekg(ios::beg);}

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

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

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


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