Вход на сайт
C++
NEW 10.02.05 21:07
в ответ Murr 10.02.05 19:02
В ответ на:Ну вот не читает оно у меня до конца строки.
---------------
Читает [f]gets(), a через [f]scanf надо правильно задавать параметры - там их 5 штук - все читается.
Ну вот что за народ такой??? Я потому сюда и пришёл, что сам разобраться не смог и никакой хэлп не помог. Нет чтоб рассказать и объяснить хотя бы на примере, начинаются высказывания типа "я умный, а ты - бестолочь." Покажи мне хоть одного, кто сразу всё мог!!!
ПыСы: убедительная просьба не отвечать на это сообщение. я ветку не для этого открыл. спасибо!
"...вечно молодой, вечно пьяный..."
"...вечно молодой, вечно пьяный..."
NEW 10.02.05 21:35
в ответ ойМОЛОДой 10.02.05 21:07
"я умный, а ты - бестолочь."
-------------
Меня в плохих подсказках обвиняли достаточно часто. Выработалось
отсутствие реакции на подобные обвинения. Тем более, что те кто у
меня учился умеют делать эту работу и делают ее самостоятельно.
сам разобраться не смог и никакой хэлп не помог
-------------
По-этому тебе и подсказали в каком направлении копать в хелпе -
функция fscanf() и ПЯТЬ спецификаций в формате.
Подсказка вторая - ПРОБЕЛ - это тоже информация. Если не поможет -
рисуй строку на бумаге в клеточку и постарайся понять сколько
информации считывается по каждому спецификатору формата и что
будет следующим на входе.
-------------
Меня в плохих подсказках обвиняли достаточно часто. Выработалось
отсутствие реакции на подобные обвинения. Тем более, что те кто у
меня учился умеют делать эту работу и делают ее самостоятельно.

сам разобраться не смог и никакой хэлп не помог
-------------
По-этому тебе и подсказали в каком направлении копать в хелпе -
функция fscanf() и ПЯТЬ спецификаций в формате.
Подсказка вторая - ПРОБЕЛ - это тоже информация. Если не поможет -
рисуй строку на бумаге в клеточку и постарайся понять сколько
информации считывается по каждому спецификатору формата и что
будет следующим на входе.
NEW 13.02.05 16:15
в ответ Murr 10.02.05 19:13
С двумя замечаниями:
1. char FiName[100]; char LaName[100];
вместо char[] следует использовать std::string
2.
protected:
virtual ifstream& operator>>(ifstream&) {...}
virtual ofstream& operator<<(ofstream&) {...}
С какой стати они protected? Операторы ввода вывода обычно используются другими классами, и во-вторых их никогда не следует делать членами класса - это препятствует соединению ряда таких операторов в цепь.
veni, vidi... expuli
1. char FiName[100]; char LaName[100];
вместо char[] следует использовать std::string
2.
protected:
virtual ifstream& operator>>(ifstream&) {...}
virtual ofstream& operator<<(ofstream&) {...}
С какой стати они protected? Операторы ввода вывода обычно используются другими классами, и во-вторых их никогда не следует делать членами класса - это препятствует соединению ряда таких операторов в цепь.
veni, vidi... expuli
NEW 13.02.05 16:25
в ответ scorpi_ 13.02.05 16:15
С двумя замечаниями:
1. char FiName[100]; char LaName[100];
вместо char[] следует использовать std::string
------------------
Можно обойтись и char *, если понимать что будет дальше.
К тому же, если вспомнить что это пишется под СБилдером,
можно и AnsiString задействовать...
2.
protected:
virtual ifstream& operator>>(ifstream&) {...}
virtual ofstream& operator<<(ofstream&) {...}
С какой стати они protected? Операторы ввода вывода обычно используются другими классами, и во-вторых их никогда не следует делать членами класса - это препятствует соединению ряда таких операторов в цепь.
--------------------
Старая привычка. Еще с тех времен, когда IO было friend.
1. char FiName[100]; char LaName[100];
вместо char[] следует использовать std::string
------------------
Можно обойтись и char *, если понимать что будет дальше.
К тому же, если вспомнить что это пишется под СБилдером,
можно и AnsiString задействовать...
2.
protected:
virtual ifstream& operator>>(ifstream&) {...}
virtual ofstream& operator<<(ofstream&) {...}
С какой стати они protected? Операторы ввода вывода обычно используются другими классами, и во-вторых их никогда не следует делать членами класса - это препятствует соединению ряда таких операторов в цепь.
--------------------
Старая привычка. Еще с тех времен, когда IO было friend.
NEW 13.02.05 16:37
в ответ Murr 13.02.05 16:25
Можно обойтись и char *, если понимать что будет дальше.
Можно, но не нужно (пример можно, где это оправдано?). И тем более нет смысла употреблять char* отвечая новичку.
можно и AnsiString задействовать...
Опять же, можно, но не нужно. Лучше насколько это возможно использовать стандарт.
veni, vidi... expuli
Можно, но не нужно (пример можно, где это оправдано?). И тем более нет смысла употреблять char* отвечая новичку.
можно и AnsiString задействовать...
Опять же, можно, но не нужно. Лучше насколько это возможно использовать стандарт.
veni, vidi... expuli
NEW 13.02.05 16:53
в ответ scorpi_ 13.02.05 16:37
Можно, но не нужно (пример можно, где это оправдано?).
-------------------------
Хммм... Последний раз это делал, когда надо было в довольно большом
проекте встроить контроль вывода и при этом существующий код не
должен был меняться. Пришлось дополнить структуру FILE и переопределить f*().
И тем более нет смысла употреблять char* отвечая новичку.
--------------------------
По-этому там и оставлены char[100], чтобы не возникало непонятных
вопросов.
Опять же, можно, но не нужно.
Лучше насколько это возможно использовать стандарт.
-------------------------
Не всегда. Если вместо полностью соответствующей стандарту прожки
в 400 строк, можно написать не-стандарт на 40, то нет смысла писать
стандарт.
-------------------------
Хммм... Последний раз это делал, когда надо было в довольно большом
проекте встроить контроль вывода и при этом существующий код не
должен был меняться. Пришлось дополнить структуру FILE и переопределить f*().
И тем более нет смысла употреблять char* отвечая новичку.
--------------------------
По-этому там и оставлены char[100], чтобы не возникало непонятных
вопросов.
Опять же, можно, но не нужно.
Лучше насколько это возможно использовать стандарт.
-------------------------
Не всегда. Если вместо полностью соответствующей стандарту прожки
в 400 строк, можно написать не-стандарт на 40, то нет смысла писать
стандарт.
13.02.05 17:13
в ответ Murr 13.02.05 16:53
Если вместо полностью соответствующей стандарту прожки в 400 строк, можно написать не-стандарт на 40, то нет смысла писать стандарт.
Можно пример этих 40 строк? Я утверждаю, что моя standard-conform программа не будет существенно отличаться по длине.
veni, vidi... expuli
Можно пример этих 40 строк? Я утверждаю, что моя standard-conform программа не будет существенно отличаться по длине.
veni, vidi... expuli
NEW 13.02.05 17:53
в ответ scorpi_ 13.02.05 17:13
Можно пример этих 40 строк?
---------------
А смысл? Функциональность там все одно будет близкой к нулю и
портировать это не придется.
Кстати, тот код, что приведен автором вопроса, на 95% рабочий. То,
что там нужно добавить три строки - пустяки и не играет никакой роли.
А сравнивать надо именно с тем, что приведено тобой в качестве
стандарта - будет как раз 1:10 по объему.
---------------
А смысл? Функциональность там все одно будет близкой к нулю и
портировать это не придется.
Кстати, тот код, что приведен автором вопроса, на 95% рабочий. То,
что там нужно добавить три строки - пустяки и не играет никакой роли.
А сравнивать надо именно с тем, что приведено тобой в качестве
стандарта - будет как раз 1:10 по объему.
NEW 13.02.05 18:25
в ответ ойМОЛОДой 10.02.05 16:27
Во-первых, если у Вас строка типа Петров Иван 45, то вызов функции должен выглядеть следующим образом: fscanf( fp, "%s %s %d\n", &lastname, &name, &age ,0); Но, в реальной жизни эту функцию лучше не использовать, так как fscanf копирует поля в переменные не проверяя достаточен ли размер буфера, то есть с этой функцией очень легко получить buffer overflow. Если Вам надо прочитать строку, то используйте fgets, с дальнейшей разбивкой строки на поля с помощью strtok, strchr и других функций из strng.h, с дальнейшей проверкой полученных полей.
Но, вс╦ вышесказанное собственно говоря неважно, так как Вы написали в заголовке С++, в то время как вс╦ вышесказанное относится к С. Я Вам очень порекомендую почитать книгу для начинающих по С++, например Accelerated C++ Энди К╦нига. И кроме того, пользуйтесь насколько это возможно стандартным С++. В данном случае std::string, std::ifstream и так далее.
В С++ стиле Ваша задача будет выглядеть примерно так:
Но, вс╦ вышесказанное собственно говоря неважно, так как Вы написали в заголовке С++, в то время как вс╦ вышесказанное относится к С. Я Вам очень порекомендую почитать книгу для начинающих по С++, например Accelerated C++ Энди К╦нига. И кроме того, пользуйтесь насколько это возможно стандартным С++. В данном случае std::string, std::ifstream и так далее.
В С++ стиле Ваша задача будет выглядеть примерно так:
#include <cstdlib>
#include <string>
#include <fstream>
#include <deque>
template< class ch, class tr, class al >
std::deque<std::basic_string<ch, tr, al> > split( const std::basic_string<ch, tr, al>& line, const ch* space )
{
std::deque< std::basic_string<ch, tr, al> > v;
for ( std::basic_string<ch, tr, al>::size_type end = 0,
begin = line.find_first_not_of( space, end ,0);
begin != std::basic_string<ch, tr, al>::npos;
begin = line.find_first_not_of( space, end ) )
{
end = line.find_first_of( space, begin ,0);
if ( end == std::basic_string<ch, tr, al>::npos )
v.push_back( line.substr( begin ) ,0);
else
v.push_back( line.substr( begin, end - begin ) ,0);
}
return v;
}
class Person
{
std::string name_;
std::string lastname_;
int age_;
public:
Person( const std::string& line ) : age_(0)
{
std::deque<std::string> v = split( line, " " ,0);
if ( v.size() != 3 )
throw std::runtime_error( "invalid line" ,0);
name_ = v[0];
lastname_ = v[1];
age_ = atoi( v[2].c_str() ,0);
}
const std::string& name() const { return name_; }
const std::string& lastname() const { return lastname_; }
int age() const { return age_; }
};
int main()
{
std::deque< Person > students;
std::ifstream students_file( "data.dat" ,0);
while( students_file.good() && !students_file.eof() )
{
std::string buffer;
std::getline( students_file, buffer ,0);
students.push_back( Person( buffer ) ,0);
}
}
И наконец - хотя и бывают ситуации, когда текст файлы можно использовать, но вс╦ же почитайте книжки по базам данных.
veni, vidi... expuli
NEW 13.02.05 18:30
в ответ scorpi_ 13.02.05 18:01
Ну хорошо, уговорил.
СБилдер 5(6). Строим МИДАС-сервер на базе RemoteDataModule.
Если не знаешь, то там идет обмен пакетами - на клиента
уходит полный набор, а возвращается дельта-пакет -
изменено, удалено, новое.
Со стороны базы весь доступ идет через процедуры - там
их 4 штуки и они вполне согласованы по параметрам.
Дополнительно - сделан базовый класс (на базе RemoteDataModule)
c функцией переброски полей из пакета в параметры процедур.
Ну разумеется где не надо не перебрасывается первичный ключ.
Размер кода, не считая *.h, как раз примерно 40 строк - один
switch на три позиции.
Будем строить что-то похожее на базе STL&STD?
Только перед тем как строить вспомни об двух вещах:
- СБилдер базируется на VCL(Паскаль)
- имет RTTI
СБилдер 5(6). Строим МИДАС-сервер на базе RemoteDataModule.
Если не знаешь, то там идет обмен пакетами - на клиента
уходит полный набор, а возвращается дельта-пакет -
изменено, удалено, новое.
Со стороны базы весь доступ идет через процедуры - там
их 4 штуки и они вполне согласованы по параметрам.
Дополнительно - сделан базовый класс (на базе RemoteDataModule)
c функцией переброски полей из пакета в параметры процедур.
Ну разумеется где не надо не перебрасывается первичный ключ.
Размер кода, не считая *.h, как раз примерно 40 строк - один
switch на три позиции.
Будем строить что-то похожее на базе STL&STD?
Только перед тем как строить вспомни об двух вещах:
- СБилдер базируется на VCL(Паскаль)
- имет RTTI
NEW 19.02.05 17:07
в ответ Chipolino 19.02.05 13:02
Да, заглянул в стандарт, согласно нему ты прав, правда мой вариант тоже работает. Но суть собственно не в этом, а в том, что эту функцию можно использовать только в том случае, если ты стопроцентно уверен в том, что все поля в файле не длиннее твоих переменных.
NEW 20.02.05 00:06
в ответ scorpi_ 19.02.05 17:07
Твой вариант "работает" только потому, что в прототипе финкции указано,
что не надо проверять соответствии числа и типов параметров. Для Плюсов,
как и для Паскаля, это нонсенс...
К тому же - не все компиляторы правильно обрабатывают этот код, опуская
операцию получения адреса.
что не надо проверять соответствии числа и типов параметров. Для Плюсов,
как и для Паскаля, это нонсенс...
К тому же - не все компиляторы правильно обрабатывают этот код, опуская
операцию получения адреса.
