Member
Статус: Не в сети Регистрация: 15.11.2003 Откуда: Moscow\Russia
Нужно написать курсовую, база данных студентов, сложность заключается в том, что писать надо под ДОС.
Это не делфи где кинул на форму табличку и заполнил.
Все рисовать нужно вручную!
всвязи с этим есть такие вопросы:
1.Какой функцией можно изменить шрифт, цвет текста, цвет фона, для украшения главной менюшки ?
2. Я хочу, чтоб у меня было 2 файла: первый главный, где содержится функция MAIN, а 2 содержит вспомогательные функции, которые в этой MAIN используются. Как это сделать?
Я понимаю с помощью #include, но чего-то у меня не получается.
Хотел бы увидеть простенький примерчик.
M9IC 1. Какой компилятор используешь (BC31?,Watcom,Lcc,Gcc,DJGCC,Zortech,TopSpeed,Turbo?) ? ( наверно просто C?).
2. Лучше использовать ещё больше файлов ( обычно их надо обединить в проект ).
3. Какую библиотеку используешь для "главной меню": текст или графика (видео-режим)?
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
M9IC Ну изменить шрифт не получится(есть конечно вариант, но думаю с ассемблером тебе будет ещё сложнее), а цветом текста и фона можно рулить с помощью cprintf(...). Возьми помощь по функциям textcolor, textbackground, textattr. Порядок такой: сначала выставляешь этими функциями атрибуты текста, потом выставляешь курсор на нужную позицию, а потом выводишь текст с помощью cprintf. Можно написать функцию типа:
Код:
//протестировано в Borland C++3.1 #include <conio.h> void MyTextOut(int x, int y, int color, int backcolor, char* str){ textcolor(color); textbackground(backcolor); gotoxy(x,y); cprintf("%s",str); } int main(){ MyTextOut(35,12,10,1,"хэлло ворд"); return 0; }
Но я бы обратил внимание на прямой вывод - puttext(...) крайне хороша, немного подготовительной работы, но потом офигенная скорость вывода.
Advanced member
Статус: Не в сети Регистрация: 09.06.2003 Откуда: USSR
Цитата:
Нужно написать курсовую, база данных студентов, сложность заключается в том, что писать надо под ДОС.
Я бы таких педагогов, задающих задания писать под Дос, выгонял из Института .
Если ты пишеш под Borland C, то можеш использовать Turbo Vision для построения форм, кнопок и так далее. Очень удобно. Я в свое время много программ на нем написал.
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Ray Adams Да ладно, это же интересно. Я писал прогу без Турбовижына(немного ассемблера и TV не нужен ), крайне направленную на внешний вид. В общем получилось прога, которая по скорости как вывода, так и обработки самой БД давала огромную фору ФоксПро(на 286 это было очень заметно). А смотрелась она достойно: десятки пересекающихся окон и менюшек + ввод БД который отличит от browse только заядлый фокспрошник.
Member
Статус: Не в сети Регистрация: 15.11.2003 Откуда: Moscow\Russia
Компилятор у меня Борланд С++ 5.02
Насчет файлов: естественно больше, это я к примеру сказал, но с этим вопросом я разобрался.
Для главной менюшки я не использую никаких библиотек, просто cout<<"текст" выводит в столбик возможные действия, а функция "курсор" бегает по столбику и возвращает значение действия, например:
1-удалить студента
2-добавить......
В СС++ я знаю оч.мало и времени нет, чтоб оч красиво все делать....
думаю так сойдет и понятно и визуально немного....%)
Теперь у меня возник другой вопрос:
У студента есть имя, в Делфи просто: String и не париться, а здесь массив символов(есть правда класс стринг, ноя не хочу использовать)
Так вот, написал я функцию чтоб этот массив заполнять:
#include <iostream>
#include <stdio>
void INPUTstring(char s[],int lim)
{
char c;
int i=0;
while((c=getchar())!=' ' && i<=lim)
{
s[i]=c; i++;
}
if (c==' ') s[i]=' ';
if (i>lim) s[--i]=' ';
}
void OUTPUTstring(char s[])
{
int i=0;
while(s[i]!=' ') cout<<s[i++];
}
Так вот допустим у меня массив s1[20], а я ввожу 30 символов функция делает все правильно:
пихает в массив первые 20, остальные отбрасывает, НО есть проблемка, если я ввожу этой функцией 2 массива, то она сама берет и оставшиеся 10 символов пихает во второй массив, а мне этого совсем не надо!
Как это исправить?
Добавлено спустя 15 секунд: Компилятор у меня Борланд С++ 5.02
Насчет файлов: естественно больше, это я к примеру сказал, но с этим вопросом я разобрался.
Для главной менюшки я не использую никаких библиотек, просто cout<<"текст" выводит в столбик возможные действия, а функция "курсор" бегает по столбику и возвращает значение действия, например:
1-удалить студента
2-добавить......
В С\С++ я знаю оч.мало и времени нет, чтоб оч красиво все делать....
думаю так сойдет и понятно и визуально немного....%)
Теперь у меня возник другой вопрос:
У студента есть имя, в Делфи просто: String и не париться, а здесь массив символов(есть правда класс стринг, ноя не хочу использовать)
Так вот, написал я функцию чтоб этот массив заполнять:
#include <iostream>
#include <stdio>
void INPUTstring(char s[],int lim)
{
char c;
int i=0;
while((c=getchar())!='\n' && i<=lim)
{
s[i]=c; i++;
}
if (c=='\n') s[i]='\n';
if (i>lim) s[--i]='\n';
}
void OUTPUTstring(char s[])
{
int i=0;
while(s[i]!='\n') cout<<s[i++];
}
Так вот допустим у меня массив s1[20], а я ввожу 30 символов функция делает все правильно:
пихает в массив первые 20, остальные отбрасывает, НО есть проблемка, если я ввожу этой функцией 2 массива, то она сама берет и оставшиеся 10 символов пихает во второй массив, а мне этого совсем не надо!
Как это исправить?
У тебя была проблема в том, что при чтении лимита символов ты бросаешь входной поток(читай - файл(stdin)) недочитанным и следущее обращение к потоку автоматом пытается дочитать остатки. Я переоформил это дело - теперь поток дочитывается до конца, но при достижении лимита строка просто не наращивается.
Я первый раз пользовался этой функцией - не естественная она, хотя привыкнуть можно. Гораздо проще обрабатывать символы по мере ввода( c=getch() ), чем весь поток сразу(а именно так происходит в данном случае).
зы:
Цитата:
У студента есть имя, в Делфи просто: String и не париться, а здесь массив символов(есть правда класс стринг, ноя не хочу использовать)
Как говорится РТФМ. Не так страшен чёрт как его малюют - когда привыкнешь всё становится предельно просто.
Member
Статус: Не в сети Регистрация: 15.11.2003 Откуда: Moscow\Russia
хм а как реализовать с функцией getch(ну я использую getche, чтоб видно было что вводишь)
если я изменю код:
oid INPUTstring(char s[],int lim)
{
char c;
int i=0;
while((c=getche())!='\n' && i<=lim)
{
s[i]=c; i++;
}
if (c=='\n') s[i]='\n';
if (i>lim) s[--i]='\n';
}
все работает, только почему-то у меня вводятся символы через пробел,т.е. если я хочу ввести допустим имя Паша, то будет так:
_п_а_ш_а ( _ этим я обозначил пробел), и в массив запишется с пробелом. как сделать понормальному?
Народ, вы меня добиваете просто. Краткий экскурс в историю.
В С строка представляет собой массив символов с управляющем нолём на конце. Вы пишете сложные функции и зачем-то считываете все посимвольно, когда можно написать так:
Код:
char str[21]; gets(str);
если нужно быть уверенным, что длина строки не превышает чего-то там, то мона объявить буферную строку из 128 символов (под досом нельзя вводить больше за раз. клавиатурный буфер не резиновый). дальше есть функця strlen(str), которая возвращает в аккурат длину строки (int). Проверяем буферную строку на вшивость, и если она подходит, копируруем её в строку возвращаемую. Но стоит ли ради 3 строчек текста писать отдельную функцию, на вызов которой тратится много времени?
Member
Статус: Не в сети Регистрация: 19.10.2004 Откуда: Киев
M9IC писал(а):
Нужно написать курсовую, база данных студентов, сложность заключается в том, что писать надо под ДОС. Это не делфи где кинул на форму табличку и заполнил. Все рисовать нужно вручную! всвязи с этим есть такие вопросы:
1.Какой функцией можно изменить шрифт, цвет текста, цвет фона, для украшения главной менюшки ?
2. Я хочу, чтоб у меня было 2 файла: первый главный, где содержится функция MAIN, а 2 содержит вспомогательные функции, которые в этой MAIN используются. Как это сделать? Я понимаю с помощью #include, но чего-то у меня не получается. Хотел бы увидеть простенький примерчик.
пока вроде все %)
Поговори с преподом, если он не знает этого так это не означает что это не следует делать, может все таки ему надо напомнить что уже какбы прогресс наблюдается и не стоит особо в досе проги такого класа писать.
В Builder проще. Возьми учебник хороший. Популярен например Архангельский да и пиши.
Добавлено спустя 9 минут, 22 секунды: ...кстати исспользуйте переменные типа register если например делаете очитку, обнуление больших массивов да и так в коротко живущих операциях, помогает поднять скорость, это как бы запрос на исспользовании регистров (исправил по замечанию Root- a)процессора, только при этом к переменным такого вида нельзя применять все что связанно с адресом (ссылки , указатели о них забудьте).
_________________ Многие вещи нам непонятны не потому, что понятия наши слабы; но потому, что сии вещи не входят в круг наших понятий.
Последний раз редактировалось Mr_User 28.11.2004 5:14, всего редактировалось 1 раз.
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
Mr_User
Цитата:
это как бы запрос на исспользовании кеша процессора
а мат. часть подучить? ключевое слово register помещает нечто не в кэш проца, а в его регистры, количество которых никогда большим не было... если считаете иначе, то киньте, плиз, ссылку, подтверждающую Вашу фразу
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
Member
Статус: Не в сети Регистрация: 19.10.2004 Откуда: Киев
Root писал(а):
Mr_User
Цитата:
это как бы запрос на исспользовании кеша процессора
а мат. часть подучить? ключевое слово register помещает нечто не в кэш проца, а в его регистры, количество которых никогда большим не было... если считаете иначе, то киньте, плиз, ссылку, подтверждающую Вашу фразу
Никакого источника нет, это мои мысли, судя по всему неверные.
Я че то сам подумал что это должен быть кеш, а какие регистры вы имеете ввиду EAX, EBX, ECX .....? Скорее всего я ошибся и вовсе забыл про существование только что указанных. А эти регистры где то обозначаются на блок схеме процессора а то непонятно где они, это я из ассемблера вспомнил что они есть.
_________________ Многие вещи нам непонятны не потому, что понятия наши слабы; но потому, что сии вещи не входят в круг наших понятий.
время жизни<-----------класс памяти-------------->область видимости
|
локальна /автоматический--|
от входа в функцию < |
до выхода из нее \ регистровые---|
|
время жизни для них статические--|
глобально от начала
программы до конца
программы
Класс памяти указывается при объявлении переменных Класс памяти _ Тип _ Имя
регистровые переменные, в отличие от автоматических, размещаются не в Основной Памяти, а в регистрах центрального процессора.
При невозможности разместить переменную в регистрах транслятор преобразует ее в класс автоматических.
Следствие: Для регистровых переменных невозможно вычислить адрес.
Вывод: если очень надо можно хоть все переменные объявлять регистровыми. Если места не будет ее переведут в класс auto (то есть в обычные).
Код:
register тип имя;
Но на современных процах разницы вы всё равно не почувствуете. так что это лишнее.
Member
Статус: Не в сети Регистрация: 19.10.2004 Откуда: Киев
0x[4d6178] [ASCII] писал(а):
Классы памяти локальных переменных.
время жизни<-----------класс памяти-------------->область видимости | локальна /автоматический--| от входа в функцию < | до выхода из нее \ регистровые---| | время жизни для них статические--| глобально от начала программы до конца программы
Класс памяти указывается при объявлении переменных Класс памяти _ Тип _ Имя регистровые переменные, в отличие от автоматических, размещаются не в Основной Памяти, а в регистрах центрального процессора. При невозможности разместить переменную в регистрах транслятор преобразует ее в класс автоматических.
Следствие: Для регистровых переменных невозможно вычислить адрес. Вывод: если очень надо можно хоть все переменные объявлять регистровыми. Если места не будет ее переведут в класс auto (то есть в обычные).
Код:
register тип имя;
Но на современных процах разницы вы всё равно не почувствуете. так что это лишнее.
смотря что за программа, а вообще то разницу можно увидеть. Учитывая задержки оперы и т.д. Ну по моему с Атлонами там по лучше например у FX-51 FX-55 с встроенным контроллером памяти, но память там регтстровая с ЕСС так что.......
А исспользовать я считаю нужно, там где надо
_________________ Многие вещи нам непонятны не потому, что понятия наши слабы; но потому, что сии вещи не входят в круг наших понятий.
0x[4d6178] [ASCII] Разница между регистрами и даже кешпамятью по времени очень большая, особенно в маленьких циклах!!
Модификатор register просто советует компилятору, что это часто используемая переменная ( что современные компиляторы знают нехуже ). При работе с переменной, которая находится в памяти, практически всегда она загружается в регистр, что-то делается а потом назад в память. И на то как долго она находится в регистре как раз и влияет register (идеал-всегда). И по-этому у регистровых переменны, есть выделенная память, адрес на которую можно получить.
Пример:
Код:
#include <stdio.h>
int main ( void ) { register int i = 0; int *pi = &i; printf( "Addr = %p\n", pi ); }
Выдает: Addr = 0022FF8C
В хороших компиляторах (MS VC++ ), в одом участке памяти может находится 2 переменные. Пока одна в регистре, вторая в памяти. Когда надо работать со второй то делается xchg [reg],[addr], что экономит проц. время. Но всё что здесь сказано менятся при использовании модификатора volatile.[/b][/code]
Member
Статус: Не в сети Регистрация: 19.10.2004 Откуда: Киев
Всем кто читает привет.
Вопрос
необходимо выделить динамическую память используя С-шную ф-цию
calloc:
вот обявлен класс в File1.h
Код:
class CompileClass_LW1 { public: //------------------------ CompileClass_LW1(void); int *Calculate(void); int Read_File(void); int Calc_digits(const char *t_bp_p,bool marker_float ); //double complex Complex_matrix( ); //double complex K21(float *w_pt );
private: //----------------------
protected://---------------------- unsigned int num_mas; struct About_pasport { int N; int N_inp; int N_out; int N_f; double f_min; double f_max; }About_pasport_var; struct About_comp { char Type_comp[10]; unsigned int Junction_points[3][1]; float Parametr; char Full_Name_comp[50]; } ;
};
А вот File1.cpp где я пытался создать экземпляр структуры в динамической области памяти при помощи calloc, только вот незнаю можно ли, и если можно, то как, сделать так чтоб ф-ция calloc возвращала указатель на многомерный массив, в даном случае мне необходимо сделать двумерный. С одномерным массивом все работает, но как вы наверное заметили мне пришлось для каждого элемента R,C,VT,VD....создавать отдельный экземпляр (в смысле имя, а хотелось бы двумерный массив ), а еслиб их было не 6 а скажем 100 то это весьма кстати было бы, да и просто самому интересно, кроме того необходимо чтоб int Read_File(void); возвращала return адрес экземпляров ,а в массиве это проще реализовать .
Код:
//------------------------------------------------ int CompileClass_LW1::Read_File(void) { Form1->RichEdit1->Lines->Clear(); int *read_elem; read_elem = Calculate(); extern AnsiString Name; extern FILE *fp1; char temp_buff[1500]={'\0'}; const char *t_bp = 0; int R_elem = 0; int C_elem = 0; int E_elem = 0; int VT_elem = 0; int VD_elem = 0; int A_elem = 0; Form1->StatusBar1->Panels->Items[0]->Width=300; Form1->StatusBar1->Panels->Items[0]->Text="Процессы: Начало сканирования файла...."; unsigned int n_lines = 0, n_lines_data = 0;
................................................................... ................................................................... и т.д.
Колличество элементов в стобцах необходимо чтоб изменялось, тоесть считывает файл, к примеру там 4 резистора, всех остальных меньше так вот я хочу создать массив структур (размер определяется по максимальному количеству из элементов, в даном случае R больше) тоесть массив About_comp_var[6][ Max_elem[0] ] (хоть и нерационально но удобно) R C VT VD E A ______________________________ R1 C1 VT1 VD1 E1 A1 R2 C2 E2 A2 R3 R4
Код:
int *CompileClass_LW1::Calculate(void) { static int Max_elem[6]; extern AnsiString Name; char calc_buff[1500]={'\0'}; FILE *fp0=0; fp0=fopen(Name.c_str(), "a+") ; Form1->StatusBar1->Panels->Items[0]->Width=200; Form1->StatusBar1->Panels->Items[0]->Text="Ïðîöåñû: Ïîäñ÷åò êîë-âà ýëåìåíòîâ â ìàñèâå ñòðóêòóðû...."; if(Name == "") { MessageDlg("Ôàéë íå îòêðûò.",mtWarning,TMsgDlgButtons()<<mbOK,0); } if (Name != "") { while( fgets(calc_buff, sizeof(calc_buff),fp0) != NULL ) { //-----------Calculate---------------------------------------------- for(register unsigned short int i=0; i < strlen(calc_buff); i++) { if( calc_buff[i] == '\n' || calc_buff[i] == ';' ) num_mas++; if ( calc_buff[i] == 'R' ) Max_elem[0]=Max_elem[0]+1; if ( calc_buff[i] == 'C' ) Max_elem[1]=Max_elem[1]+1; if ( calc_buff[i] == 'E' ) Max_elem[2]=Max_elem[2]+1; if ( calc_buff[i] == 'VT' ) Max_elem[3]=Max_elem[3]+1; if ( calc_buff[i] == 'VD' ) Max_elem[4]=Max_elem[4]+1; if ( calc_buff[i] == 'A' ) Max_elem[5]=Max_elem[5]+1; } } // while........ }// if ()..... fclose(fp0); //Beep(); /* for(register unsigned short int temp=0,i=0; i < 5-1; i++) for(register unsigned short int j = i + 1; j < 5; j++) if (Max_elem[i]>Max_elem[j]) { temp = Max_elem[i]; Max_elem[i]=Max_elem[j]; Max_elem[j]=temp; } */ Form1->StatusBar1->Panels->Items[0]->Text="Процессы: Подсчет количества элементов завершен"; return Max_elem; [b]/* здесь я забанил цикл сортировки, но при двумерном массиве необходимо было бы вернуть максимальное число из типов компо- нентов Max_elem[0] */[/b] }
Вот опратор C++ new дает такую возможность, но только так :
About_comp (*About_comp_var)[6] = new About_comp [read_elem[0]][6];
а вот таким образом уже отказываеться, ну это и понятно ему же необходимо знать размер блока, ячейки памяти
About_comp (*About_comp_var)[6] = new About_comp [6][read_elem[0]];
В общем у кого какие идеи есть, help ?
Аааа и кстати вот я придумал такой вариант, компилятор пропустил его но результата я не добился, где то семантическая зарыта:
// About_comp_var = (About_comp ((*)[6]))calloc(6*num_mas,sizeof(About_comp));
_________________ Многие вещи нам непонятны не потому, что понятия наши слабы; но потому, что сии вещи не входят в круг наших понятий.
Member
Статус: Не в сети Регистрация: 19.10.2004 Откуда: Киев
Avaddon писал(а):
Mr_User 1. Тебе calloc дорог как память? Не хочешь использовать std::vector< std::vector<About_comp> > ? 2. Извини, но код ужасный.
Цитата:
int Read_File(void); возвращала return адрес экземпляров
А описать ее как type *Read_File(void); сложно?
Тю, так я и написал что собираюсь это сделать, если цытируеш так цитируй уже целиком законченую мысль а не отрывки, а звучит она так :"....кроме того необходимо чтоб int Read_File(void); возвращала return адрес экземпляров , а в массиве это проще реализовать . ". А вот ретурнить то что записано сюда :
, я еще как то не придумал, а с массивом никаких проблем бы не было
На счет кода, так я лабу делаю, так что особо напрягаться не собираюсь, просто вопрос возник.
Если все же кто знает, просьба помочь. [/b]
Добавлено спустя 3 минуты, 7 секунд:
Avaddon писал(а):
Mr_User 1. Тебе calloc дорог как память? Не хочешь использовать std::vector< std::vector<About_comp> > ? .......................................................
А вот на счет этого просьба подробнее
_________________ Многие вещи нам непонятны не потому, что понятия наши слабы; но потому, что сии вещи не входят в круг наших понятий.
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
Цитата:
Вопрос по C++.как calloc вернуть указат. на двумерн. массив?
собственно по этому. Привожу схему как писать:
Код:
char **a; a=calloc(..); // выделяем память под массив указателей for (int i=0, i<N; i++) a[i] = calloc(...) // выделяем память под двумерный массив тут
надеюсь, это немного поможет... придется расставить параметры у функций и может сделать явное приведение типов.
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения