Я начинающий, подскажите как...(Все вопросы начинающих - постить только здесь!!!)
В C++ есть такое ключевое слово - template для написания шаблонов. Объясните, хотя бы вкратце, что это за шаблоны такие, для чего они нужны и как их использовать? Ни в одном учебнике по C++ ничего не говорится про шаблоны. Нет их и в книге Б. Страуструпа. Видимо, они появились в C++ недавно?
Как это у Страуструпа нет шаблонов !!! :eek: Язык программирования С++,специальное издание ,глава 13.стр.377.Во втором издании - глава 8.Да в любом учебнике по С++,что значит нет ? Не смеши! Хотя бы Стэнли Липпман.Язык программирования С++.Вводный курс. Джосьюттис,Вандервуд Шаблоны С++. Целая книга о шаблонах. Поиск по форуму рулит.
Ясно, просто у меня первое издание (1995 г.), там template даже не упомянуто в списке ключевых слов:
class const continue default delete
do double else enum extern
float for friend goto if
inline int long new operator
overload public register return short
sizeof static struct switch this
typedef union unsigned virtual void
while
Идентификаторы signed и volatile зарезервированы для применения в будущем.
А глава 8 описывает использование потоков.
Увы. :( Хотя, возможно, у меня просто устаревшая литература (1995-2000 гг., а шаблоны, как я понял, появились позже - в Borland C++ 3.1, например, их нет).
Насчет второй ссылки - там неполный вариант книги, только первые 2 главы, где не говорится про шаблоны. Но на том же сайте я нашел еще одну книгу Липпмана (шаблоны там описаны): http://anatolix.naumen.ru/files/books/lippman_ruz.zip
Сейчас посмотрю книгу по третьей ссылке. Вообще-то я уже находил документацию по шаблонам, но она не была рассчитана на начинающих (тех, вообще не знаком с шаблонами).
Как я понял, шаблон - это расширение перегрузки функций, и он позволяет использовать одну и ту же функцию или класс для обработки данных различных типов, чтобы не писать несколько вариантов?
Я не начинающий, программирую на C++ уже 8 лет, но раньше не знал про существование шаблонов.
Так, начинаю что-то понимать... :) Рассмотрим такой пример на C:
int nsqr(int x)
{
return x*x;
}
float fsqr(float x)
{
return x*x;
}
int main(int argc, char* argv[])
{
int n;
float f;
printf("Hello World!\n");
n=2;
printf("%d^2=%d\n", n, nsqr(n));
f=1.5;
printf("%.2f^2=%.2f\n", f, fsqr(f));
return 0;
}
Очевидно, что объявлять много функций неудобно. Проще было бы, если бы была одна функция sqr(x), работающая и с целыми, и с вещественными числами.
В Си для такой задачи используются макросы:
#define SQR(x) ((x)*(x))
int main(int argc, char* argv[])
{
int n;
float f;
printf("Hello World!\n");
n=2;
printf("%d^2=%d\n", n, SQR(n));
f=1.5;
printf("%.2f^2=%.2f\n", f, SQR(f));
return 0;
}
Но макросы часто становятся непредсказуемыми (например, SQR(n++)), кроме того, они сильно увеличивают код, если описание макроса длинное, а используется он часто.
В C++ появилось новое средство для решения данной проблемы, называемое шаблонами. Вот тот же пример на C++:
template<class T> T sqr(T x)
{
return x*x;
}
int main(int argc, char* argv[])
{
int n;
float f;
printf("Hello World!\n");
n=2;
printf("%d^2=%d\n", n, sqr(n));
f=1.5;
printf("%.2f^2=%.2f\n", f, sqr(f));
return 0;
}
Надеюсь, я нигде не ошибся? В Visual C++ это работает. :)
//----------------
int func(int);
void vivod(int);
//----------------
void main ()
{
clrscr();
int x,y;
scanf ("%d",&x);
y = func(x);
vivod (y);
getch();
}
//=======================================================
int func(int a)
{
int i;
for (i=0; a>0; a--)
i++;
return i;
}
//=======================================================
void vivod (int b)
{
int i;
int mas; //
for (i=0; i<b; i++) // данный цикл и вывод не важны.
printf ("%d", mas);
}
Суть моего вопроса заключается в том, что мне не понятно почему не получается зарезирвировать массив. При компиляции этого кода выдается сообщение об ошибке "Constant expression required". Он резервирует массив только если указать число эллементов в ручную. например /* int mas[10] */. а если описать какую либо переменную, придать ей значение (не важно каким способом), и описать массив используя эту переменную компилятор выдает ошибку приведенную выше.
//----------------
int func(int);
void vivod(int);
//----------------
void main ()
{
clrscr();
int x,y;
scanf ("%d",&x);
y = func(x);
vivod (y);
getch();
}
//=======================================================
int func(int a)
{
int i;
for (i=0; a>0; a--)
i++;
return i;
}
//=======================================================
void vivod (int b)
{
int i;
int mas; //
for (i=0; i<b; i++) // данный цикл и вывод не важны.
printf ("%d", mas);
}
Суть моего вопроса заключается в том, что мне не понятно почему не получается зарезирвировать массив. При компиляции этого кода выдается сообщение об ошибке "Constant expression required". Он резервирует массив только если указать число эллементов в ручную. например /* int mas[10] */. а если описать какую либо переменную, придать ей значение (не важно каким способом), и описать массив используя эту переменную компилятор выдает ошибку приведенную выше.
потому как на этапе компиляции под переменную (массив) выделяется определенное кол-во памяти, если туда засунуть переменную, компилятор не может предугадать размер резервируемой памяти.
выход: создавать динамически int *mas = new int;
PS: после использования не забыть удалить delete []mas;
выход: создавать динамически int *mas = new int;
PS: после использования не забыть удалить delete []mas;
А можно ли как нибудь обойти эту ошибку? Просто к моменту создания массива значение переменной будет определенно.
p.s.
благодарю за ответ. познавательно*
читай внимательно
p.s.
благодарю за ответ. познавательно*
Или объявить константную переменную:
или
По моему тут лишний знак "="...
А вообще, какой способ объявления констант в c++ лучше? Вроде, в учебниках рекомендуют const, но в исходниках чаще используют #define. Неужели дело только в том, что авторы исходников хотят, чтоб если потребуется, их проект с меньшими затратами труда мог быть переделан для c-компиляторов?
Лучше без #define. Все, что можно достаточно просто сделать без препроцессора, лучше делать без препроцессора.
В связи с этим вопрос к опытным: что предпочтительней выбрать - чистое WinAPI, MFC, WTL или лучше всего в конце концов Qt (и просто, и кроссплатформенность). Вопроса ребром о кроссплатформенности не стоит, просто насколько я видел, работать с Qt гораздо проще и нагляднее, чем с MFC или WTL.
Подскажите, пожалуйста!
А вообще, какой способ объявления констант в c++ лучше? Вроде, в учебниках рекомендуют const, но в исходниках чаще используют #define. Неужели дело только в том, что авторы исходников хотят, чтоб если потребуется, их проект с меньшими затратами труда мог быть переделан для c-компиляторов?
:) Естественно лишний. По инерции.
Понятие "лучшего" не существует. Определите для себя единую нотацию и следуйте ей.
Использование констант в данном плане гораздо более предпочтительно - вы получаете четко названную область памяти и с четко определенным типом.
В связи с этим вопрос к опытным: что предпочтительней выбрать - чистое WinAPI, MFC, WTL или лучше всего в конце концов Qt (и просто, и кроссплатформенность). Вопроса ребром о кроссплатформенности не стоит, просто насколько я видел, работать с Qt гораздо проще и нагляднее, чем с MFC или WTL.
Подскажите, пожалуйста!
Это тема для начинающих а не для тех, кому не о чем поговорить. Просьба в дальнейшем это учитывать. По вопросу что вам выбрать - на форуме тема обсасывалась как минимум десяток раз. используйте поиск - если сами не в состоянии определиться что вам надо.
Размещение в тематическом форуме изначально флеймовых тем не приветствуется и наказывается.
1) Если написать вот так:
char n;
cin>>n;
то после запуска программы надо будет ввести некоторый символ, после чего нажать Enter, после чего этот введённый символ запишется в переменную n.
Собственно вопрос: можно ли сделать так, чтобы Enter не нажимать? То есть чтобы после нажатия, допустим, клавиши "a" в переменную n записывался символ "а".
2) Нужно вывести на экран некую строку. Далее дождаться нажатия кнопки Enter и вывести другую строку.
Как вывести строку понятно, а вот как определить нажатие клавиши Enter?
Заранее спасибо!
Как вывести строку понятно, а вот как определить нажатие клавиши Enter?
Тебе нужно получить код символа.:)
Сообщения windows----WM_KEYDOWN, WM_KEYUP.
код клавиши Enter -13;
1) Если написать вот так:
char n;
cin>>n;
то после запуска программы надо будет ввести некоторый символ, после чего нажать Enter, после чего этот введённый символ запишется в переменную n.
Собственно вопрос: можно ли сделать так, чтобы Enter не нажимать? То есть чтобы после нажатия, допустим, клавиши "a" в переменную n записывался символ "а".
#include <iostream.h>
#include <conio.h>
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
char a;
a = getch();
cout << a << "UUUU";
return 0;
}
2) Нужно вывести на экран некую строку. Далее дождаться нажатия кнопки Enter и вывести другую строку.
Как вывести строку понятно, а вот как определить нажатие клавиши Enter?
Заранее спасибо!
cout <<"rrr";
2CilCatblack я не предупреждал вас что ответы не по теме приравниваются к флейму и наказываются? Предупреждаю
- задавать некий вопрос
- считывать ответ пользователя; ответ на русском языке
- задавать некий вопрос
- считывать ответ пользователя; ответ на английском языке
- дальше всё по новой
В результате пользователю постоянно придётся менять раскладку клавиатуры. Спрашивается: можно ли раскладку клавиатуры менять как-то в программе, чтобы пользователю этого делать не приходилось?
- задавать некий вопрос
- считывать ответ пользователя; ответ на русском языке
- задавать некий вопрос
- считывать ответ пользователя; ответ на английском языке
- дальше всё по новой
В результате пользователю постоянно придётся менять раскладку клавиатуры. Спрашивается: можно ли раскладку клавиатуры менять как-то в программе, чтобы пользователю этого делать не приходилось?
LoadKeyboardLayout("00000419", KLF_ACTIVATE); // Русский
Использование для консоли:
SendMessage(hWnd,WM_INPUTLANGCHANGEREQUEST,1,(DWORD)LoadKeyboardLayout("00000419", 0));
LoadKeyboardLayout("00000419", KLF_ACTIVATE); // Русский
Использование для консоли:
SendMessage(hWnd,WM_INPUTLANGCHANGEREQUEST,1,(DWORD)LoadKeyboardLayout("00000419", 0));
А можно, пожалуйста, поподробней, как это используется?
Попробовал вставить первый код - написалось сообщенеи об ошибке - не известно KLF_ACTIVATE... Попробовал второй - тоже ошибки.
Посмотрел в инете - вроде бы для этих функций нужно что-то типа такого написать:
Попробовал - не помогло.
Даже если просто написать:
int main(){
return 0;
}
выдаются ошибки...
Что делать?
И кстати, что означает "для консоли"? :confused:
Вот программа:
int main(){
LoadKeyboardLayout("00000409", KLF_ACTIVATE);
LoadKeyboardLayout("00000419", KLF_ACTIVATE);
return 0;
}
говорит: `KLF_ACTIVATE' undeclared (first use this function) :confused:
#include <iostream.h>
#include <conio.h>
#include <windows.h>
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
char a;
a = getch();
cout << a << "\tIs EN";
HWND hWnd = GetForegroundWindow();
SendMessage(hWnd,WM_INPUTLANGCHANGEREQUEST,1,(DWORD)LoadKeyboardLayout("00000419", 0));
cout <<'\n';
a = getch();
cout << a << "\tIs RU";
return 0;
}
[/highlight]
#include <iostream.h>
#include <conio.h>
#include <windows.h>
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
char a;
a = getch();
cout << a << "\tIs EN";
HWND hWnd = GetForegroundWindow();
SendMessage(hWnd,WM_INPUTLANGCHANGEREQUEST,1,(DWORD)LoadKeyboardLayout("00000419", 0));
cout <<'\n';
a = getch();
cout << a << "\tIs RU";
return 0;
}
[/highlight]
Ввёл... Вот что мне ответили:
E:\1.c: In function `int main()':
E:\1.c:11: warning: implicit declaration of function `int GetForegroundWindow(...)'
E:\1.c:11: warning: initialization to `void *' from `int' lacks a cast
E:\1.c:12: `WM_INPUTLANGCHANGEREQUEST' undeclared (first use this function)
E:\1.c:12: (Each undeclared identifier is reported only once
E:\1.c:12: for each function it appears in.)
E:\1.c:12: warning: implicit declaration of function `int LoadKeyboardLayout(...)'
E:\1.c:12: warning: implicit declaration of function `int SendMessage(...)'
Failure
ОС: WinXP
компилятор: g++ (хотя я точно не знаю, ибо не в курсе, как это определить...)
В таком случае - вам необходимо собирать ваш проект с библиотекой User32.lib (указать в командной строке дополнительную опцию). Посмотрите в справке как это правильно сделать в вашем случае, я просто не помню, а так как конкретный компилятор вы не указали, гадать не собираюсь. Кроме этого, может быть вам понадобятся еще библиотеки - смотрите описание конкретных функций.
Вероятнее всего - или в интернете, или у себя, в примерах к вашему компилятору вы найдете пример make-файла - в котором как правило указываються все зависисмости - создайте его и вам не нужно будет каждый раз указывать командную строку.
В таком случае - вам необходимо собирать ваш проект с библиотекой User32.lib (указать в командной строке дополнительную опцию). Посмотрите в справке как это правильно сделать в вашем случае, я просто не помню, а так как конкретный компилятор вы не указали, гадать не собираюсь. Кроме этого, может быть вам понадобятся еще библиотеки - смотрите описание конкретных функций.
"конкретный компилятор" - вроде Jens' File Editor
Справки нету...
Вероятнее всего - или в интернете, или у себя, в примерах к вашему компилятору вы найдете пример make-файла - в котором как правило указываються все зависисмости - создайте его и вам не нужно будет каждый раз указывать командную строку.
Вот makefile из примеров:
%.exe : %.c
gcc $< -o $@ -Wl,-s -Os
all: $(EXE) massey.scr
clean:
@del *.exe
@del *.o
@del *.org
@del *.scr
massey.scr: glmuss.c
gcc -Os -Wl,-s -mwindows glmuss.c -o massey.scr -lscrnsave -ladvapi32
Что с ним делать - не имею ни малейшего представления:(
Warning codekbd.cpp 5: Unreachable code
....
Warning codekbd.cpp 84: Unreachable code
почему это происходит, что сделано не правильно, и как решить эту проблему, не меняя сути программы :confused:
main.cpp
#include <conio.h>
#include "codekbd.cpp"
void main()
{
int res;
int port =0x60;
do{
clrscr();
res = inportb(port);
cout<<"Порт: "<<hex<<port<<endl;
cout<<"Скан код (Hex): "<<hex<<res<<endl;
cout<<"Скан код (Dec): "<<dec<<res<<endl;
cout<<"ASCII код: "<<(char)res<<endl;
cout<<"Символ: "<<symbol(res);
}while(getch()!=27);
}
codekbd.cpp
{
switch (result){
case 1:return "ESC";break;
case 2:return "1";break;
case 3:return "2";break;
case 4:return "3";break;
case 5:return "4";break;
case 6:return "5";break;
case 7:return "6";break;
case 8:return "7";break;
case 9:return "8";break;
case 10:return "9";break;
case 11:return "0";break;
case 12:return "-";break;
case 13:return "=";break;
case 14:return "Bksp";break;
case 15:return "Tab";break;
case 16:return "Q";break;
case 17:return "W";break;
case 18:return "E";break;
case 19:return "R";break;
case 20:return "T";break;
case 21:return "Y";break;
case 22:return "U";break;
case 23:return "I";break;
case 24:return "O";break;
case 25:return "P";break;
case 26:return "[";break;
case 27:return "]";break;
case 28:return "Enter";break;
case 29:return "Ctrl";break;
case 30:return "A";break;
case 31:return "S";break;
case 32:return "D";break;
case 33:return "F";break;
case 34:return "G";break;
case 35:return "H";break;
case 36:return "J";break;
case 37:return "K";break;
case 38:return "L";break;
case 39:return ";";break;
case 40:return "'";break;
case 41:return "`";break;
case 42:return "Shft";break;
case 43:return "\\";break;
case 44:return "Z";break;
case 45:return "X";break;
case 46:return "C";break;
case 47:return "V";break;
case 48:return "B";break;
case 49:return "N";break;
case 50:return "M";break;
case 51:return ",";break;
case 52:return ".";break;
case 53:return "/";break;
case 55:return "*";break;
case 59:return "F1";break;
case 60:return "F2";break;
case 61:return "F3";break;
case 62:return "F4";break;
case 63:return "F5";break;
case 64:return "F6";break;
case 65:return "F7";break;
case 66:return "F8";break;
case 67:return "F9";break;
case 68:return "F10";break;
case 71:return "Home";break;
case 72:return "Up";break;
case 73:return "Page Up";break;
case 74:return "-";break;
case 75:return "Left";break;
case 77:return "Right";break;
case 78:return "+";break;
case 79:return "End";break;
case 80:return "Down";break;
case 81:return "Page Down";break;
case 82:return "0";break;
case 83:return "Delete";break;
case 86:return "\\";break;
case 87:return "F11";break;
case 88:return "F12";break;
default:return "";break;
}
return "NULL";
}
А return "NULL" вообще никогда не вызовется, т.к. его перекрывает default:return "";
codekbd.cpp
{
switch (result){
case 1:return "ESC";break;
case 2:return "1";break;
case 3:return "2";break;
case 4:return "3";break;
case 5:return "4";break;
case 6:return "5";break;
case 7:return "6";break;
case 8:return "7";break;
case 9:return "8";break;
case 10:return "9";break;
case 11:return "0";break;
case 12:return "-";break;
case 13:return "=";break;
case 14:return "Bksp";break;
case 15:return "Tab";break;
case 16:return "Q";break;
case 17:return "W";break;
case 18:return "E";break;
case 19:return "R";break;
case 20:return "T";break;
case 21:return "Y";break;
case 22:return "U";break;
case 23:return "I";break;
case 24:return "O";break;
case 25:return "P";break;
case 26:return "[";break;
case 27:return "]";break;
case 28:return "Enter";break;
case 29:return "Ctrl";break;
case 30:return "A";break;
case 31:return "S";break;
case 32:return "D";break;
case 33:return "F";break;
case 34:return "G";break;
case 35:return "H";break;
case 36:return "J";break;
case 37:return "K";break;
case 38:return "L";break;
case 39:return ";";break;
case 40:return "'";break;
case 41:return "`";break;
case 42:return "Shft";break;
case 43:return "\\";break;
case 44:return "Z";break;
case 45:return "X";break;
case 46:return "C";break;
case 47:return "V";break;
case 48:return "B";break;
case 49:return "N";break;
case 50:return "M";break;
case 51:return ",";break;
case 52:return ".";break;
case 53:return "/";break;
case 55:return "*";break;
case 59:return "F1";break;
case 60:return "F2";break;
case 61:return "F3";break;
case 62:return "F4";break;
case 63:return "F5";break;
case 64:return "F6";break;
case 65:return "F7";break;
case 66:return "F8";break;
case 67:return "F9";break;
case 68:return "F10";break;
case 71:return "Home";break;
case 72:return "Up";break;
case 73:return "Page Up";break;
case 74:return "-";break;
case 75:return "Left";break;
case 77:return "Right";break;
case 78:return "+";break;
case 79:return "End";break;
case 80:return "Down";break;
case 81:return "Page Down";break;
case 82:return "0";break;
case 83:return "Delete";break;
case 86:return "\\";break;
case 87:return "F11";break;
case 88:return "F12";break;
default:return "";break;
}
return "NULL";
}
А вообще, это жуть!
Почему бы не использовать обычный массив?
И возвращать надо, кстати, не char*, а const char*.
1. Не включена библиотека для манипулятора hex (требуется #include <iomanip>).Зато включен исполняемый файл: #include "codekbd.cpp"...
2. Явно требуется строчка using namespace std; так как ввод-вывод почти в стиле c++.
3. Почему void main(), а не int?
и т.д.
Кроме того, автор вопроса ошибается, что компилятор ругается на 4-й case. Он ругается на первый.
кирилица при выводе в файл
пробувал
BOOL SetConsoleCP(UINT wCodePageID);
BOOL SetConsoleOutputCP(UINT wCodePageID);
но абракадабра остается :-\
вот пример с потоками, но чет он не работает(в фаиле пустота):
...
int main()
{
fstream file;
file.open("d:\\text.txt");
if (!file) {cout << "error in open file\n"; getch();
return 1;}
char str[80];
cin >> str;
file << str;
file.close();
}
подскажите пожалуйста, а лучше дайте готовый код или ссылку...
Заголовочный файл fstream.h определяет класс выходного файлового потока с именем ofstream. Используя объекты класса ofstream, ваши программы могут выполнять вывод в файл. Для начала вы должны объявить объект типа ofstream, указав имя требуемого выходного файла как символьную строку, что показано ниже:
ofstream file_object("FILENAME.EXT");
Если вы указываете имя файла при объявлении объекта типа ofstream, C++ создаст новый файл на вашем диске, используя указанное имя, или перезапишет файл с таким же именем, если он уже существует на вашем диске Следующая программа OUT_FILE.CPP создает объект типа ofstream и затем использует оператор вставки для вывода нескольких строк текста в файл BOOKINFO.DAT:
#include <fstream.h>
void main(void)
{
ofstream book_file("BOOKINFO.DAT");
book_file << "Учимся программировать на языке C++, " << "Вторая редакция" << endl;
book_file << "Jamsa Press" << endl;
book_file << "22.95" << endl;
}
В данном случае программа открывает файл BOOKINFO.DAT и затем записывает три строки в файл, используя оператор вставки.
но думаю проблема в том што в нево все выводится в кодировке ASCII (дос) а когда ты открываешь блокном то видишь в ANSI (виндовс) и отсюда абракадабра, проверить просто - либо если пользуешся тотал коммандером нажать F3 (внутренний просмотровщик) там можно через меню "вид" просмотреть и в дос и в виндовс кодировке, а можно в блокноте, установив шрифт.. Terminal кажется... точно не помню
добавлено:
аа.. сразу не заметил, ты хочешь именно при выводе в АНСИ преобразовывать чтоб мона было блокнотом открывать штоль?
ввожу, например "русский текст", и в файле(открываемом блокнотом) "русский текст" записано
_http://www.realcoding.net/article/view/1872#r6 тут не совсем то что тебе нужно, "Как конвертировать строку из кодировки WIN в KOI" но может сам принцип понять поможет
вот пару ссылок еще
_http://sources.codenet.ru/download/1652/%F3%F7%E5%E1%ED%FB%E5_%EF%F0%E8%EC%E5%F0%FB.html
_http://www.sysman.ru/index.php?showtopic=3584
_http://www.sources.ru/cpp/faqs/78.htm
_http://forum.sysman.ru/index.php?showtopic=6678&st=30
_http://sources.codenet.ru/download/1652/%F3%F7%E5%E1%ED%FB%E5_%EF%F0%E8%EC%E5%F0%FB.html
не компилируется >_<
пользуюсь DevC++ 4.9.9.2
error`ы:
`gotoxy' undeclared (first use this function)
`clrscr' undeclared (first use this function)
[Warning] comparison is always false due to limited range of data type
{
unsigned char *cstr=str;//"unsigned" - чтоб избежать предупреждений комп-ра
for(; *cstr; cstr++)
{
if(*cstr>=128 && *cstr<=175)
*cstr+=64;
else if(*cstr>=224 && *cstr<=239)
*cstr+=16;
else if(*cstr==252)
*cstr=185;
}
return str;
}
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
SetConsoleCP(GetACP());
fstream file;
file.open("text.txt", ios::out);
char str[80];
if (!file)
{
cout << "error in open file\n";
cin >> str;//getch();
return 1;
}
cin >> str;
file << str;
file.close();
return 0;
}
Недоумение как правило вызывают подобные вопрошающие - не считающие необходимым привести хотя бы, текст ошибки которую они получают. Я предполагаю что это ошибка кода спрашивающего на уровне генотипа.