Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.93
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
#1

Чтение всего файла fstream - C++

06.05.2014, 23:29. Просмотров 2259. Ответов 50
Метки нет (Все метки)

В общем мне казалась задача вполне очевидна и частая считать файл целиком в строку, но почему-то я не нашёл ничего готового (типа fstream::readAll()).
Оператор >> игнорирует пробельные символы, вычитал отсюда fstream - символ пробела что можно использовать getline, но меня смущает что туда нужно передавать буфер заранее известного размеры, вам не кажется что это как-то дико и в Си стиле? По-моему в современном мире функция должна сама создать буфер и вернуть мне его. В общем как вы читаете весь файл и затем записываете его в переменную?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.05.2014, 23:29
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Чтение всего файла fstream (C++):

Fstream - чтение из файла - C++
подскажите начинающему программисту как читать файл целиком.. например последовательность чисел

Заменить чтение из файла аналогом fstream - C++
char fileName; printf("Enter file name: "); scanf("%255s", fileName); FILE *open = fopen(fileName, "r"); ...

Чтение файла в массив символов используя fstream - C++
Добрый день. Нужно считать файл в массив символов(vector). Использую fstream.

Как начать чтение файла сначала после Getline с первой строчки в fstream? - C++
Пишу программу,которая читает строки их текстового файла и передаёт их в поле Edit1 поочерёдно,по нажатию кнопки.Когда строки...

Не могу разобраться. Чтение и вывод на экран всего содержимого файла .txt на консоль - C++
#include <cstdio> #include <iostream> #include <conio.h> #include <fstream> using namespace std; void main() { ...

fstream не работает и чтение и запись - C++
Добрый день! Не пойму, почему введение функции getline становится причиной того, что запись в файл не идет. Если getline убрать, то все...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
newbie666
Заблокирован
07.05.2014, 15:19 #16
Цитата Сообщение от OrmaJever Посмотреть сообщение
Да можно конечно, но наследование то зачем?
приведи перечь по твоему мнению не достающих функций стандартного std::string
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 15:54  [ТС] #17
1) replace. Да я знаю что он там есть, но он делает немного другое. Нужно что бы все вхождения строки "from" она заменила на "to". from может быть как меньше to так и больше (по длине).
2) toLower, toUpper. Мелочь, но мне нужно.
3) из-за приоритетов у оператора += нельзя сделать цепочку вызовов (str += "some str" += "append" += "this is string" ), только раставлять скобки (((str += "some str") += "append") += "this is string"), что по-моему дико поэтому я переопределяю оператор << в котором вызываю append. Ах да, с append можно сделать цепочку, но по мне нагляднее оператор <<.
stima
463 / 312 / 26
Регистрация: 22.03.2011
Сообщений: 1,021
Завершенные тесты: 2
07.05.2014, 16:15 #18
Ты платишь только за то что используешь. (с) Страуструп.
Нужно -> реализовывай.

Добавлено через 54 секунды
п.с. Перефразирую readAll/toLower/etc это излишество, которое можно реализовать самому.
newbie666
Заблокирован
07.05.2014, 16:16 #19
галимые доводы, всё это делается элементарно.
Ну если ты хочешь свой спецовый класс - делай класс String, в конструктор которог передавай строку и делай с ней что хочешь ёлки палки, ни от чего наследоваться не надо... Что, без примера никак ?
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 16:27  [ТС] #20
Цитата Сообщение от stima Посмотреть сообщение
readAll/toLower/etc это излишество, которое можно реализовать самому.
Цитата Сообщение от newbie666 Посмотреть сообщение
галимые доводы, всё это делается элементарно.
Так это же круто, я не против! Я это и реализовал сам, но из-за 3 методов мне пришлось добавлять 3 конструктора и 2 оператора=, потому что просто так из родительского класса они вызываться не хотят. А вот теперь ещё и нужно ити искать какой конструктор отвечает за эту строку
C++
1
std::string str = oss.str();
и тоже его дописывать, а завтра я захочу использовать ещё какие нибудь операторы или передам в конструктор что-то другое (что вполне принимает std::string), и снова придётся писать бессмысленный метод который просто вызовет такой же только родительский.
stima
463 / 312 / 26
Регистрация: 22.03.2011
Сообщений: 1,021
Завершенные тесты: 2
07.05.2014, 16:43 #21
Цитата Сообщение от OrmaJever Посмотреть сообщение
бессмысленный метод который просто вызовет такой же только родительский.
Я не понял, Вам метод нужен?, тогда он не бессмысленный. Иначе зачем он Вам?

п.с. Такое чувство, что разговор скатывается к: "Я хочу кнопку, при нажатии на которую все будет работать. При этом я ничего делать не хочу".
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 17:09  [ТС] #22
Цитата Сообщение от stima Посмотреть сообщение
Я не понял, Вам метод нужен?, тогда он не бессмысленный. Иначе зачем он Вам?
Окей, видимо вы реально не понимаете о чём я. Пример
C++
1
2
3
4
5
6
7
8
9
10
11
12
namespace HL{ 
    class string : public std::string
    {
    public:
        string &operator<<( const char );
        string &operator<<( const char * );
        string &operator<<( const string & );
 
        string toLower( void ) const;
        string toUpper( void ) const;
        string replace( const char *, const char * );
    };
далее при создании
C++
1
2
HL::string str;
str = "some string";
Код
error: no match for 'operator=' (operand types are 'HL::string' and 'const char*')
хотя как вы понимаете в std::string есть operator=(const char *).
Проблема то в том что компилятор не берёт его из родительского класса, а ищет только в моём. И что бы этот код работал нужно добавить
C++
1
2
3
4
5
HL::string &HL::string::operator= ( const char *str )
{
    assign( str );
    return *this;
}
бесполезность метода очевидна? Такая же беда и с конструкторами
C++
1
HL::string str("some value");
вежливо попросит меня создать конструктор HL::string(const char *), и выглядеть он будет так
C++
1
HL::string(const char *str) : std::string( str ) {}
То есть родительские методы переносятся частично, да я смогу к обьекту HL::string применить родительский метод append, но с операторами и конструкторами такая вот беда. Я один считаю что это не правильно?
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
07.05.2014, 17:53 #23
Цитата Сообщение от OrmaJever Посмотреть сообщение
То есть родительские методы переносятся частично, да я смогу к обьекту HL::string применить родительский метод append, но с операторами и конструкторами такая вот беда. Я один считаю что это не правильно?
Родительские методы переносятся все (кроме конструкторов - думаю понятно почему, если не понятно, то стоит поразмышлять о том, что конструктор привязан к типу).
Оператор operator= переносится из базового класса. Но есть такая штука, как сокрытие методов. Поясню на более очевидном примере:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
class B
{
public:
    B & foo(char const *) { std::cout << "B::foo\n"; return *this; }
};
 
 
class A : public B
{
public:
    A & foo(int) { std::cout << "A::foo\n"; return *this; }
};
 
 
int main()
{
    A a;
 
    //a.foo("test"); // ошибка
    a.foo(1); // OK
}
Видишь, метод foo из базовго класса недоступен. Его скрыл метод foo из наследника.
Теперь вернемся к operator=. Дело в том, что в твоем наследнике HL::string уже есть operator=, это автогенерированный
C++
1
HL::string & operator=(HL::string const &)
вот он-то и скрыл оператор из базового string. В С++ есть стандартный способ сделать скрытую функцию видимой.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace HL{ 
    class string : public std::string
    {
    public:
        using std::string::operator=;
 
        string &operator<<( const char );
        string &operator<<( const char * );
        string &operator<<( const string & );
 
        string toLower( void ) const;
        string toUpper( void ) const;
        string replace( const char *, const char * );
    };
Добавлено через 13 минут
Да, в С++11 появилась возможность наследовать и конструкторы. Точно так же, через using.
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 18:19  [ТС] #24
DrOffset, ну вот! Вы же тот человек который пришёл и всё разложил по полочкам. Огромное спасибо!

Добавлено через 15 минут
Хотя всё таки небольшая непоняточка осталась.
Берём пример Jupiter'a
C++
1
2
3
4
std::ifstream file("text.txt");
std::ostringstream oss;
oss << file.rdbuf();
std::string str = oss.str();
он работает. Но если заменить std::string на HL::string (в котором написано using std::string::string, то компилятор не может найти подходящий конструктор, а именно
Код
error: no matching function for call to 'HL::string::string(std::basic_ostringstream<char>::__string_type)'
хотя реально показывает что искал среди всех конструкторов std::string, да и в доках у std::string нету конструктора подходящего для
C++
1
std::basic_ostringstream<char>::__string_type
.
Как его найти?
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
07.05.2014, 19:09 #25
Цитата Сообщение от OrmaJever Посмотреть сообщение
то компилятор не может найти подходящий конструктор, а именно
Потому что именно такого конструктора нет. Его придется написать самостоятельно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace HL{ 
    class string : public std::string
    {
    public:
        string(std::string const & value)
            : std::string(value)
        {} 
 
        string &operator<<( const char );
        string &operator<<( const char * );
        string &operator<<( const string & );
 
        string toLower( void ) const;
        string toUpper( void ) const;
        string replace( const char *, const char * );
    };
Почему так? Потом что методы наследника, если они определены с такой же сигнатурой, всегда имеют приоритет перед перенесенными методами из базового класса. Т.е. автогенерированный конструктор копирования HL::string заменил наследованный конструктор копирования из std::string, поэтому его и нет в HL::string.

OrmaJever, предупреждая дальнейшие вопросы, советую тщательно изучить тему связанную с наследованием конструкторов в С++11. Иначе, пользоваться инструментом не понимая как он работает довольно опасно. Начать можно отсюда. А потом настоятельно рекомендую почитать параграф 12.9 стандарта С++.
Если все-таки что-то будет не понятно, то спрашивай тогда здесь
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 20:21  [ТС] #26
Ладненько со всем этим по очереди разберусь. Тогда ещё один я думаю простой вопрос, если я создам чистый класс
C++
1
class A {}
Какие конструкторы/методы компилятор сам в него добавит?
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
07.05.2014, 20:42 #27
Цитата Сообщение от OrmaJever Посмотреть сообщение
Какие конструкторы/методы компилятор сам в него добавит?
1. Конструктор по-умолчанию (без параметров);
2. Конструктор копирования;
3. Деструктор;
4. Оператор присваивания (copy-assignment).
В С++11 еще добавляются:
5. Конструктор перемещения;
6. Оператор перемещения (move-assignment).

Все эти методы будут являться тривиальными в данном случае (trivial).

Добавлено через 9 минут
Конструктор по-умолчанию не добавляется, если определен любой из пользовательских конструкторов.
Остальные методы не добавляются, если существуют определенные пользователем альтернативы.
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 20:45  [ТС] #28
Правильно ли я понял
1) myClass( void );
2) myClass( const myClass & );
3) ~myClass( void );
4) void operator=( ? ); // какой параметр? myClass & ?
5) myClass( myClass && );
6) myClass& operator= ( myCLass && );

5 и 6 я взял из описания std::string, но не понимаю что они делают. && - ссылка на ссылку или логический оператор AND?
DrOffset
7090 / 4231 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
07.05.2014, 20:50 #29
Цитата Сообщение от OrmaJever Посмотреть сообщение
&& - ссылка на ссылку или логический оператор AND?
Это так называемая rvalue reference. C помощью них организована семантика перемещения в С++11.
Цитата Сообщение от OrmaJever Посмотреть сообщение
Правильно ли я понял
1) myClass();
2) myClass( const myClass & );
3) ~myClass();
4) myClass & operator=(const myClass &);
5) myClass( myClass && );
6) myClass& operator= ( myCLass && );
void в скобках не надо писать. Эта надобность была в С, из-за того, что func() обозначала не функцию без параметров, а функцию с бесконечным числом параметров, т.е. аналог func(...). В С++ такого нет.
OrmaJever
9 / 9 / 0
Регистрация: 10.11.2011
Сообщений: 241
07.05.2014, 20:54  [ТС] #30
Цитата Сообщение от DrOffset Посмотреть сообщение
void в скобках не надо писать. Эта надобность была в С, из-за того, что func() обозначала не функцию без параметров, а функцию с бесконечным числом параметров, т.е. аналог func(...). В С++ такого нет.
Я знаю, но по моему красиво В общем вроде всё понятно. Спасибо ещё раз.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.05.2014, 20:54
Привет! Вот еще темы с ответами:

Запись/чтение структуры через fstream - C++
Доброго времени суток! у меня есть несколько вопросов по поводу файловых потоков. 1. Как можно записать/прочитать массив структур в...

Запись/чтение структур (файлы) + разница между FILE * и <fstream> - C++
Всем привет. Порыскал по форуму, погуглил... Решения есть, но они не ясны (что, почему да как) и не все работают. Однако, я так и не нашёл...

fstream, создание файла - C++
Привет всем, не могу справиться с проблемой. fstream file(FILE,ios::in|ios::out|ios::binary); файл не создается, но если создать...

Запись в середину файла - fstream - C++
Как можно при помощи fstream (хотелось бы именно им, потому что он умеет и читать, и писать) записать что-либо в середину файла (или куда...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
07.05.2014, 20:54
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru