Deutsch

C++

336  1 2 все
ойМОЛОДой местный житель10.02.05 21:07
ойМОЛОДой
NEW 10.02.05 21:07 
в ответ Murr 10.02.05 19:02
В ответ на:

Ну вот не читает оно у меня до конца строки.
---------------
Читает [f]gets(), a через [f]scanf надо правильно задавать параметры - там их 5 штук - все читается.


Ну вот что за народ такой??? Я потому сюда и пришёл, что сам разобраться не смог и никакой хэлп не помог. Нет чтоб рассказать и объяснить хотя бы на примере, начинаются высказывания типа "я умный, а ты - бестолочь." Покажи мне хоть одного, кто сразу всё мог!!!
ПыСы: убедительная просьба не отвечать на это сообщение. я ветку не для этого открыл. спасибо!
"...вечно молодой, вечно пьяный..."

"...вечно молодой, вечно пьяный..."
#21 
ойМОЛОДой местный житель10.02.05 21:09
ойМОЛОДой
NEW 10.02.05 21:09 
в ответ digital_pilot 10.02.05 17:29
Такого зверя я ещё не видел. Попробую разобраться. Спасибо!
"...вечно молодой, вечно пьяный..."
"...вечно молодой, вечно пьяный..."
#22 
ойМОЛОДой местный житель10.02.05 21:10
ойМОЛОДой
NEW 10.02.05 21:10 
в ответ gendy 10.02.05 17:29
Уже убедился, что фигню не посоветуешь. Посмотрим, чего из насоветованного в итоге получится, потом напишу.
"...вечно молодой, вечно пьяный..."
"...вечно молодой, вечно пьяный..."
#23 
Murr местный житель10.02.05 21:35
Murr
NEW 10.02.05 21:35 
в ответ ойМОЛОДой 10.02.05 21:07
"я умный, а ты - бестолочь."
-------------
Меня в плохих подсказках обвиняли достаточно часто. Выработалось
отсутствие реакции на подобные обвинения. Тем более, что те кто у
меня учился умеют делать эту работу и делают ее самостоятельно.
сам разобраться не смог и никакой хэлп не помог
-------------
По-этому тебе и подсказали в каком направлении копать в хелпе -
функция fscanf() и ПЯТЬ спецификаций в формате.
Подсказка вторая - ПРОБЕЛ - это тоже информация. Если не поможет -
рисуй строку на бумаге в клеточку и постарайся понять сколько
информации считывается по каждому спецификатору формата и что
будет следующим на входе.
#24 
scorpi_ студент13.02.05 16:01
13.02.05 16:01 
в ответ digital_pilot 10.02.05 17:29
#include<fstream.h>
ifstream src;


Sorry, но по стандарту, действительному с 1998 года, писать надо

#include <fstream>
std::ifstream src;


veni, vidi... expuli

#25 
scorpi_ студент13.02.05 16:15
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
#26 
Murr местный житель13.02.05 16:25
Murr
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.
#27 
scorpi_ студент13.02.05 16:37
NEW 13.02.05 16:37 
в ответ Murr 13.02.05 16:25
Можно обойтись и char *, если понимать что будет дальше.
Можно, но не нужно (пример можно, где это оправдано?). И тем более нет смысла употреблять char* отвечая новичку.
можно и AnsiString задействовать...
Опять же, можно, но не нужно. Лучше насколько это возможно использовать стандарт.
veni, vidi... expuli
#28 
Murr местный житель13.02.05 16:53
Murr
NEW 13.02.05 16:53 
в ответ scorpi_ 13.02.05 16:37
Можно, но не нужно (пример можно, где это оправдано?).
-------------------------
Хммм... Последний раз это делал, когда надо было в довольно большом
проекте встроить контроль вывода и при этом существующий код не
должен был меняться. Пришлось дополнить структуру FILE и переопределить f*().
И тем более нет смысла употреблять char* отвечая новичку.
--------------------------
По-этому там и оставлены char[100], чтобы не возникало непонятных
вопросов.
Опять же, можно, но не нужно.
Лучше насколько это возможно использовать стандарт.
-------------------------
Не всегда. Если вместо полностью соответствующей стандарту прожки
в 400 строк, можно написать не-стандарт на 40, то нет смысла писать
стандарт.
#29 
scorpi_ студент13.02.05 17:13
NEW 13.02.05 17:13 
в ответ Murr 13.02.05 16:53
Если вместо полностью соответствующей стандарту прожки в 400 строк, можно написать не-стандарт на 40, то нет смысла писать стандарт.
Можно пример этих 40 строк? Я утверждаю, что моя standard-conform программа не будет существенно отличаться по длине.
veni, vidi... expuli
#30 
Murr местный житель13.02.05 17:53
Murr
NEW 13.02.05 17:53 
в ответ scorpi_ 13.02.05 17:13
Можно пример этих 40 строк?
---------------
А смысл? Функциональность там все одно будет близкой к нулю и
портировать это не придется.
Кстати, тот код, что приведен автором вопроса, на 95% рабочий. То,
что там нужно добавить три строки - пустяки и не играет никакой роли.
А сравнивать надо именно с тем, что приведено тобой в качестве
стандарта - будет как раз 1:10 по объему.
#31 
scorpi_ студент13.02.05 18:01
NEW 13.02.05 18:01 
в ответ Murr 13.02.05 17:53
Стандартный С++ по объёму будет как раз меньше.
veni, vidi... expuli
#32 
scorpi_ студент13.02.05 18:25
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 и так далее.
В С++ стиле Ваша задача будет выглядеть примерно так:
#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

#33 
Murr местный житель13.02.05 18:30
Murr
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
#34 
scorpi_ студент13.02.05 18:50
NEW 13.02.05 18:50 
в ответ Murr 13.02.05 18:30
Ты бы ещё VB компоненту упомянул. Всё остальное в данной программе нельзя написать на стандатных плюсах? Короче говоря кончай флеймить.
veni, vidi... expuli
#35 
Murr местный житель13.02.05 18:56
Murr
NEW 13.02.05 18:56 
в ответ scorpi_ 13.02.05 18:50
В том то и дело, что в СБилдере все пишется в Плюсах, но далеко не в
Стандартных Плюсах, что имеет свои большие плюсы и некоторые
минусы.
А что такое VB компонента?
#36 
Chipolino знакомое лицо19.02.05 13:02
NEW 19.02.05 13:02 
в ответ scorpi_ 13.02.05 18:25
В ответ на:

Во-первых, если у Вас строка типа Петров Иван 45, то вызов функции должен выглядеть следующим образом: fscanf( fp, "%s %s %d\n", &lastname, &name, &age ,0);



По моему lastname name , без & т.к. уже адресса на начало массива char

#37 
scorpi_ скептик19.02.05 17:07
NEW 19.02.05 17:07 
в ответ Chipolino 19.02.05 13:02
Да, заглянул в стандарт, согласно нему ты прав, правда мой вариант тоже работает. Но суть собственно не в этом, а в том, что эту функцию можно использовать только в том случае, если ты стопроцентно уверен в том, что все поля в файле не длиннее твоих переменных.
#38 
Murr местный житель20.02.05 00:06
Murr
NEW 20.02.05 00:06 
в ответ scorpi_ 19.02.05 17:07
Твой вариант "работает" только потому, что в прототипе финкции указано,
что не надо проверять соответствии числа и типов параметров. Для Плюсов,
как и для Паскаля, это нонсенс...
К тому же - не все компиляторы правильно обрабатывают этот код, опуская
операцию получения адреса.
#39 
1 2 все