Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

DF2 :: ФОРУМЫ _ Программирование / Coding _ C/C++

Автор: Тарнум 01 Apr 2010, 08:58

Не нашел подобной темы, так что создал эту.

Требуется помощь в обучении C/C++.
Нужны:
1)люди, умеющие работать на этих языках, и которые могли бы понятно объяснить все человеку, не знающему их.
2)ссылки на сайты, где можно легко обучиться этим языкам.

Заранее благодарю.

Автор: gamecreator 02 Apr 2010, 17:57

обращайся. а сайт всегда один:
http://firststeps.ru/

Добавлено ([mergetime]1270220224[/mergetime]):
правда там базового ничего нет, но это решается покупкой какой-нибудь нубской книги.

Автор: etoprostoya 02 Apr 2010, 18:01

Да, без книги тут не обойтись. Вот только путёвые книги трудны для понимания новичку, а по книгам для чайников многому не научишься.

Автор: gamecreator 02 Apr 2010, 18:03

Тарнум, ты хоть на чем-то программировал?

Автор: etoprostoya 02 Apr 2010, 18:05

Книгу я имел в виду бумажную, а не электронную.

Автор: packa 02 Apr 2010, 19:02

Присоединяюся smile.gif
Тоже хочу smile.gif

Автор: feanor 02 Apr 2010, 20:25

Я С учил по первоисточнику - книге Кернигана и Ритчи.
Ну еще по советской с названием в духе "Язык С для БДСМ БЭВМ".

Потом как справочник взял Шилдта, тоже кошерная вещь.

Автор: tolich 02 Apr 2010, 20:34

Согласен. Си - по Ритчи, C++ по Страустрапу.

Добавлено ([mergetime]1270229696[/mergetime]):
Хотя я лично Си учил по мини-книжице Болски.

Автор: etoprostoya 02 Apr 2010, 20:37

http://depositfiles.com/ru/files/wtryqgl5t
Б.В.Керниган и Д.М.Ричи
PDF (1.3mb)

Автор: packa 02 Apr 2010, 21:26

А Фаронов?
Или Фавронов? Не помню как там иго...

Автор: EtherniDee 03 Apr 2010, 07:30

Фаронов: Делфи и Турбо Паскаль (разные книги). По нему осваивал я и не жалею.

Автор: Тарнум 03 Apr 2010, 14:22

Цитата(gamecreator @ 03 Apr 2010, 01:03)
Тарнум, ты хоть на чем-то программировал?

К сожалению, нет. Но хочу научиться.
P.S. Спасибо за ссылки. Обязательно посмотрю.

Автор: Тарнум 07 Apr 2010, 08:50

Программа печати "HELLO, WORLD" на языке "C" имеет вид:
MAIN ()
PRINTF("HELLO, WORLD\N");
Как пропустить эту программу — зависит от используемой вами системы. В
частности, на операционной системе "UNIX" вы должны завести исходную
программу в файле, имя которого оканчивается на ".C", например, HELLO.C, и затем
скомпилировать ее по команде
CC HELLO.C
Если вы не допустили какой-либо небрежности, такой как пропуск символа
или неправильное написание, компиляция пройдет без сообщений и будет создан
исполняемый файл с именем а.OUT . Прогон его по команде
A.OUT
приведет к выводу
HELLO, WORLD
На других системах эти правила будут иными; проконсультируйтесь с
местным авторитетом
.

Что делать обладателю Windows XP?

Автор: Chrono Syndrome 07 Apr 2010, 09:15

Для начала - спросить автора, чем он упоролся перед написанием этих строк.

Автор: etoprostoya 07 Apr 2010, 09:39

Действительно, Тарнум, почитай-ка другого автора.

Автор: Тарнум 07 Apr 2010, 10:06

Цитата(etoprostoya @ 03 Apr 2010, 03:37)
http://depositfiles.com/ru/files/wtryqgl5t
Б.В.Керниган и Д.М.Ричи
PDF (1.3mb)



Цитата(etoprostoya @ 07 Apr 2010, 16:39)
Действительно, Тарнум, почитай-ка другого автора.

Сам же мне его рекомендовал!))) Ну так дайте другого.

Автор: etoprostoya 07 Apr 2010, 10:23

Я пас. Не представляю, что предложить новичку, кроме firststeps.ru

Автор: gamecreator 07 Apr 2010, 12:15

упоролся не автор, а переводчик, не знающий С

поищи издания получше

Автор: feanor 07 Apr 2010, 12:24

Хреново, когда техлитературу переводят не специалисты, а переводчики.

В виндах родного компилятора С(++) нету емнип (а вот для С# консольный идет вместе с нетфреймворком). Так чт ставь, скажем, Code::blocks.

Добавлено ([mergetime]1270632251[/mergetime]):
Кстати. wxWidgets курил кто?

Автор: etoprostoya 07 Apr 2010, 12:30

Курил как-то, но по в маленьких дозах. smile.gif И только под С++. А то ещё под питон и другие языки есть.

Добавлено ([mergetime]1270632626[/mergetime]):
Кстати, тут, видно, что проблема не только переводчика, но и сканирования и распознавания.

Автор: gamecreator 07 Apr 2010, 12:30

не надо никаких кодблокс. пусть сразу ставит студию

Автор: feanor 07 Apr 2010, 12:39

Зачем?
Лучше не привязываться к продуктам мелкомягких. Они слишком удобны.

Автор: gamecreator 07 Apr 2010, 12:40

правильно. и позволяют сконцентрироваться на собственно программировании

Автор: feanor 07 Apr 2010, 12:44

Угу. А потом - оппа! в кодблоксе Intellisence такой кривой, что его почти что нет. В IAR'е нету автоформатирования. Компиляторы под микроконтроллеры вообще обычно не оснащены ничем, кроме подсветки синтаксиса. И сразу грууустно без таких удобных майкрософтовских рюшечек.

Автор: etoprostoya 07 Apr 2010, 12:46

Я привык к рюшечкам. smile.gif Но и в блокноте могу писать, если нужно.
А потом рюшечками править все ошибки. gigi.gif

Автор: gamecreator 07 Apr 2010, 12:53

Цитата(feanor @ 07 Apr 2010, 13:44)
В IAR'е нету автоформатирования.

в таком случае я буду писать в Notepad++ или стандартном блокноте какой-нибудь линуксовой оболочки, где все это есть. а Intellisence лишь уменьшает частоту использования мсдн.

Автор: Chrono Syndrome 09 Apr 2010, 12:45

Цитата
Компиляторы под микроконтроллеры вообще обычно не оснащены ничем, кроме подсветки синтаксиса.

Простите, а подсветка синтаксиса в компиляторе - это как) ?

Автор: gamecreator 09 Apr 2010, 20:15

фраза, конечно, забавная, но все-же он говорил о среде разработки. неосведомленные (безграмотные?) программисты любят называть их компиляторами.

Автор: feanor 09 Apr 2010, 20:42

/me пофиг.
Надо концентрироваться на программировании, а не на терминологии, не так ли?

Автор: tolich 09 Apr 2010, 20:48

Кросс-компилятор для микроконтроллера вполне может представлять себе среду программирования c редактором с подсветкой синтаксиса и не иметь утилит для компиляции из командной строки. Сам такой делал. crazy.gif

Автор: packa 09 Apr 2010, 23:14

Все понял кроме последнего поста gigi.gif

Автор: Aleee 10 May 2010, 21:24

Кстати, о рюшечках: только я считаю, что десятая студия - та еще няшка?

Автор: etoprostoya 10 May 2010, 21:48

До сих пор не ставил, ибо отзывы о бете слышал не из лучших. Ресурсоёмкая тормозогенирирующая вещь.

Автор: Aleee 10 May 2010, 22:27

Уже был официальный релиз. Ресуркоемкость, конечно, побольше чем у борланда, но и удобство все же на высоте. А что касается тормозов, ничего подобного замечено не было. Работаю с проектом ~30 Мб чистых сорсов - отличное время компиляции, никаких тормозов во время работы не бывает (Core 2 Duo P8700, 2.53 ghz; 4 gb).

Не вижу причин не посоветовать. Хотя бы попробовать.

Автор: tolich 10 May 2010, 22:30

Емнип, скорость компиляции с удобством оболочки никак не связана.

Автор: etoprostoya 10 May 2010, 22:48

Все тормоза от Intellisense, или как там его. Если его работа улучшена (постоянно создаёт и изменяет многомегабайтные NCB-файлы даже для малюсеньких проектов), то можно и попробовать. А пока и на VS2008 неплохо.

Автор: tolich 10 May 2010, 23:05

А я пока что не слезаю с шестерки. Олдфаг или Слоупок, даже не знаю.

Автор: gamecreator 11 May 2010, 15:50

олдфаг. шестерка категорически лучше 7 и 8, а вот 9 с ней еще может потягаться. 10 не видел

Автор: FBX 11 May 2010, 17:54

а у меня стоит VS 2003 .NET Enterprise Architect, чем это чревато?

Автор: packa 11 May 2010, 18:51

(Core 2 Duo P8700, 2.53 ghz; 4 gb)
Мне бы такой комп... А то всего 1\4 от этого имеется...
Зато герои не тормозят, а больше и не нада :Р

Автор: gamecreator 11 May 2010, 19:04

Цитата(FBX @ 11 May 2010, 18:54)
а у меня стоит VS 2003 .NET Enterprise Architect, чем это чревато?
скорей всего сложностями при разработке чего-то неконсольного

Автор: baratorch 13 May 2010, 20:20

А я ща перешел из вс2005про в вс2008експресс + ResEd.
Меня все устраивает, кроме того что МсднЕкспресс нихрена не знает. Но это терпимо.

Кто-нибудь знает, будет ли ВС Экспресс рабоать с полной, не экпресс МСДН?

Автор: etoprostoya 13 May 2010, 21:48

Лучше поставить какую-нибудь, но полную версию, а не Экспресс.

Автор: Тарнум 14 May 2010, 06:06

А чем тебя Экспресс-версия не устраивает? Не такая уж она и плохая. Я вот работаю с VS2008 Express-edition и не жалуюсь.

Автор: gamecreator 14 May 2010, 08:24

это как демка. в ней кучу всего урезали.

Бараторч, я мсдн вообще отдельно ставил. но тогда ее нужно ручками вызывать

Автор: EtherniDee 14 May 2010, 13:16

Ручками не сложно. MSDN отдельно, студия вообще может не стоять.

Автор: orgus 14 May 2010, 14:16

6-ка + рюшечки в виде Visual Assist + WndTabs + BCGControlBar Library

PS если не нужен net больше ни чего и не надо smile.gif

Автор: baratorch 15 May 2010, 21:48

Цитата(gamecreator @ 14 May 2010, 11:24)
это как демка. в ней кучу всего урезали.


Ну я бы не сказал что демка.
Очередную версию хайреза героев делаю в ней.
Все что мне нужно там есть, кроме редактора ресурсов - пользуюсь программой ResEd.


Цитата(gamecreator @ 14 May 2010, 11:24)
Бараторч, я мсдн вообще отдельно ставил. но тогда ее нужно ручками вызывать

Я люблю F1 понажимать.

Автор: tolich 16 May 2010, 07:32

Цитата(orgus @ 14 May 2010, 14:16)
6-ка + рюшечки

6-ка, но без "рюшечек". Если редактировать файлы Far Manager-ом, а компилировать nmake-ом, "рюшечки" помогают плохо. laugh.gif
Впрочем, ресурсы я делаю всё же в IDE. И HEX-редактор там тоже ничего, годный.

Автор: CrackedMind 19 May 2010, 00:10

Цитата
Кто-нибудь знает, будет ли ВС Экспресс рабоать с полной, не экпресс МСДН?

отлично работает.

Цитата
это как демка. в ней кучу всего урезали.

И что из этой "кучи" тебе реально не хватает? smile.gif Ну помимо отсутствия поддержки аддинов.

Добавлено ([mergetime]1274217027[/mergetime]):
Цитата
олдфаг. шестерка категорически лучше 7 и 8, а вот 9 с ней еще может потягаться. 10 не видел

Ололо. Особенно компилятор там "отличный" smile.gif

Автор: gamecreator 19 May 2010, 07:18

Цитата(CrackedMind @ 19 May 2010, 01:10)
И что из этой "кучи" тебе реально не хватает?
как минимум MFC
Цитата(CrackedMind @ 19 May 2010, 01:10)
Ололо. Особенно компилятор там "отличный" smile.gif
нормальный компилятор, не знаю что ты в нем нашел.

Автор: CrackedMind 19 May 2010, 08:18

Цитата
нормальный компилятор, не знаю что ты в нем нашел.

Не нашел соответствие стандартам

Цитата
Как минимум MFC

брр, ужас.

Автор: gamecreator 19 May 2010, 12:27

фу, достали всякие варвары, пишущие прямо на винапи, при этом поносящие мфс, которые они скорей всего и не юзали никогда.

Автор: tolich 19 May 2010, 21:14

Нет, варвары пишут на Qt. tongue.gif

Автор: etoprostoya 19 May 2010, 21:29

wxWidget хорош.

Автор: Shihad 14 Sep 2010, 18:37

Граждане сишники и кутишники, как заставить диалог открытия файлов позволять выбрать несколько файлов? Я тут надеюсь http://symmetrica.net допилить

Автор: etoprostoya 14 Sep 2010, 19:38

Надо добавить к флагам диалога OFN_ALLOWMULTISELECT (в точности написания не уверен).

Автор: tolich 14 Sep 2010, 20:01

Цитата(Shihad @ 14 Sep 2010, 18:37)
Граждане сишники и кутишники, как заставить диалог открытия файлов позволять выбрать несколько файлов?

fileDialog->setMode(QFileDialog::ExistingFiles )

Цитата(etoprostoya @ 14 Sep 2010, 19:38)
Надо добавить к флагам диалога OFN_ALLOWMULTISELECT (в точности написания не уверен).
Не уверен — не обгоняй. Речь о Qt же.

Автор: etoprostoya 14 Sep 2010, 20:30

Только сейчас вспомнил, что Шихад у нас линуксоид и ему мой метод не подойдёт.

Автор: Shihad 25 Sep 2010, 09:14

Хм. Нашел где ковырять, но толком не врубаюсь как.

Код
void MainForm::loadImage()
{      
   QFileDialog dialog(this,
    trUtf8("Open Image"), lastDir, trUtf8("Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)"));
     //  dialog -> setFileMode(QFileDialog::ExistingFiles);
   if (dialog.exec()) {
 QStringList fileNames;
 fileNames = dialog.selectedFiles();
 lastDir = dialog.directory().path();
 loadFile(fileNames.at(0));


Закомментированная строка добавлена мной. Но с ней не компилируется. В Си я не понимаю почти ничего.
Как сделать правильно?

Автор: feanor 25 Sep 2010, 09:25

Часом, не . вместо -> требует?
Попробуй dialog.setFileMode(QFileDialog::ExistingFiles); или &dialog -> setFileMode(QFileDialog::ExistingFiles);

Автор: Shihad 25 Sep 2010, 09:33

Феанор, спасибо. Работает.

Но не совсем. Похоже, в следующие строчки надо дописать цикл, чтобы файлы загружались по очереди. Сейчас загружается только первый.
Покурю еще...

Автор: tolich 25 Sep 2010, 09:49

Цитата(Shihad @ 25 Sep 2010, 09:33)
Феанор, спасибо. Работает.

Но не совсем. Похоже, в следующие строчки надо дописать цикл, чтобы файлы загружались по очереди. Сейчас загружается только первый.
Покурю еще...

Код
void MainForm::loadImage()
{      
  QFileDialog dialog(this, tr("Open Image"), lastDir, tr("Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)"));
  dialog.setFileMode(QFileDialog::ExistingFiles);
  if (dialog.exec()) {
   QStringList fileNames;
   fileNames = dialog.selectedFiles();
   lastDir = dialog.directory().path();
   for (QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it )
     loadFile(*it);
  }
}

Как-то так.

Да, мой предыдущий пост предполагал что-то вроде:
Код
QFileDialog *fileDialog = new QFileDialog(this,
   tr("Open Image"), lastDir, tr("Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)"));
fileDialog->setMode(QFileDialog::ExistingFiles );

Тем не менее, нет такого закона, который бы требовал обязательного создания объектов-диалогов в хипе.

Автор: Shihad 25 Sep 2010, 10:03

Спасибо, Толич. Тоже работает.
Авторство указал в комментариях к коду.

Автор: ChASnock 14 Jun 2012, 11:19

У меня глупенький вопрос непосредственно по языку:
где может понадобиться оператор постинкремента вместе с возвращаемым им значением? Не понимаю, зачем он нужен.

только сейчас дошло, почему си плюс плюс с двумя плюсами smile.gif

Автор: tolich 14 Jun 2012, 11:23

>> где может понадобиться оператор постинкремента вместе с возвращаемым им значением?

Код
char *strcpy( char *dest, const char *src)
{
  char *p=dest;
  while(*dest++=*src++);
  return p;
}

Автор: ChASnock 14 Jun 2012, 12:30

О как лихо.
Но, наверное, всегда его можно убрать и поставить инкремент в цикле.

Автор: Berserker 14 Jun 2012, 15:54

Разумеется.

Автор: Erolast 16 Jun 2012, 18:30

http://www.intuit.ru/department/pl/cpp/ - отличный сайт. Нету нечего лишнего, только по теме, плюс куча примеров. Единственное - там надо зарегистрироваться, а дальше тупо перебирать лекции.

Автор: feanor 16 Jun 2012, 23:57

Хм. Оказывается, назревает новая спецификация С.
http://ru.wikipedia.org/wiki/C11

Автор: Erolast 17 Jul 2012, 18:33

У меня есть такая программка:

CODE

int main()
{
setlocale (LC_CTYPE,"rus");
int x = 1;
cout << "Введите размер массива"<< endl;
cin >> x;
// ??? //
system("pause");
return 0;
}


Надо чтобы она создавала массив размером x. Можно это как-нибудь устроить? Помогите, пожалуйста.

Автор: feanor 17 Jul 2012, 18:51

В С так:

int *arr = (int*)malloc(x);
..
mfree(arr); //или free? я жертва swilib.h

В С++ через new/delete, думаю

Автор: Erolast 17 Jul 2012, 19:04

feanor, спасибо, но - как теперь его можно проинициализировать?

Автор: Bourn 17 Jul 2012, 19:08

Erolast

Код
for(int i=0;i<x;i++)
arr[i]=0;

Автор: Erolast 17 Jul 2012, 19:12

Винда ругается нехорошими словами sad.gif
А этот код вобще можно в с++ использовать? Просто я как раз в с++ написал, может из-за этого программа не работать?

Автор: Bourn 17 Jul 2012, 19:24

полный код программы для с++

Код
int main()
{
setlocale (LC_CTYPE,"rus");
int x = 1;
cout << "Введите размер массива"<< endl;
cin >> x;
int *arr=new int[x];
for(int i=0;i<x;i++)
arr[i]=0;
delete [] arr;
system("pause");
return 0;
}


если делать malloc то надо указать размер правильный т.е.
Код
int *arr = (int*)malloc(x*sizeof(int));

Автор: Erolast 17 Jul 2012, 19:30

Спасибо огромное smile.gif И тот, и другой код теперь работает. А оказывается - всего-то одного слова не хватало...

Автор: Shurup 21 Sep 2012, 12:07

Просто для понимания.

Есть массив unsigned char * [ size], где size - динамический и может быть >100 000.

Я хочу работать с ним как с потоком для последовательного чтения переменных и структур.
Правильно ли я понимаю, что для этого мне нужно сначала создать поток, затем эти "over 100Кб" записать в этот поток, а потом только читать?
Или можно заставить поток брать данные именно оттуда без дополнительного копирования?

Или я вообще мимо и мне пора завязывать с Си?

Автор: tolich 21 Sep 2012, 12:25

Если я правильно понял, тебе нужен strstream. А с C завязывай, переходи на C++.

Автор: Shurup 21 Sep 2012, 12:39

Про бесплюсный си даже и думать не собирался.

strstream? Так а как его натравить на мой массив? Кроме как ->Write(array).

Автор: tolich 21 Sep 2012, 12:41

The class describes a stream buffer that controls the transmission of elements to and from a sequence of elements stored in a char array object. Depending on how it is constructed, the object can be allocated, extended, and freed as necessary to accommodate changes in the sequence.

Автор: IvanSav 21 Sep 2012, 13:50

Единственное что сейчас эта штука называется std::stringstream а не strstream, а так да, оно:

Код
#include <sstream>
#include <iostream>

int main()
{
    char * data = new char[1024]; // данные, которые НЕ будут удалены потоком

    for (size_t i=0; i< 1024; i++)
        data[i] = rand() % 26 + 'a'; // заполняем случайными буковками


    std::ostringstream buffer;
    buffer.rdbuf()->pubsetbuf(data, 1024); // собственно установка наших данных

    std::cout << buffer.str(); // проверка
    delete [] data; // не забываем удалить данные
}


EDIT:
считал что stringstream и прочие удалят этот буфер - оказывается что нет.

Автор: Erolast 21 Sep 2012, 15:24

А еще можно написать перед вызовом main-функции "using namespace std;" и не париться с прописыванием везде "std::", вот так:

Код
#include <sstream>
#include <iostream>

using namespace std;

int main()
...

Автор: IvanSav 21 Sep 2012, 16:03

Спорный вопрос.
Файл 1

Код
using namespace std;
using namespace boost; // а что? популярная библиотечка


И получаем абсолютно бессмысленную ругань от компилятора, если используем что-то что есть и там, и там (а такого более, чем достаточно)

Файл 2
Код
using namespace boost;
using namespace std; // вполне возможно что переставили их местами или хедеры в другом порядке подключены

А это вместе с первым даст еще и приколы при линковке

Или такое:
Код
class foo
{
int max;
void bar();
};

void foo::bar(vector<int> data)
{
int count; // специально назвали так, чтоб не конфликтовать с std::max
for (size_t i=0; i<data.size(); i++)
    count = max(data[i], count);
}

Забыли что где-то max уже объявлена, а count тоже в std есть. Сидим и офигеваем от выдачи компилятора.

В std еще много неплохих имен. Например написали функцию distance(const Point* a, const Point* - расстояние между двумя точками. А вызывается std::distance - расстояние между указателями.
А еще там есть count, equal, unique, map. Список можно продолжать.

Префикс (в случае с C) или пространство имен (C++) это легкий способ выяснить откуда какая функция просто глянув на имя - неплохой бонус для читаемости кода. И меньше шансов отхватить от компилятора.

Автор: Vizit0r 21 Sep 2012, 16:10

Цитата(IvanSav @ 21 Sep 2012, 16:03) *
И получаем абсолютно бессмысленную ругань от компилятора

Это нормально - ведь это си. тут вообще 80% ошибок для неподготовленного пользователя ниочем и ведут в никуда.

Автор: Septimus 16 Dec 2012, 13:16

Ребят, такая просьба. У моего друга - проблема с С++ (он не из моего города). Сам я только Pascal проходил. А помочь другу все-таки хочется. Поможете составить программу по такой вот задачке?

Цитата
Дан двумерный целочисленный массив. Если в массиве нет элементов, делящихся на 3 без остатка, сформировать новый одномерный массив из положительных элементов двумерного массива.

Автор: gamecreator 16 Dec 2012, 13:52

друг зря взялся за это программирование

Автор: etoprostoya 16 Dec 2012, 14:10

Код
#define N 100
#define M 100
int arrin[N][M];
int arrout[N*M];
//int *arrout;
void func()
{
int x, y, z;
int is3div = 1;
for(x = 0; x < N && is3div; x++)// если находим элемент, делящийся на 3 без остатка, то дальше нет смысла считать
for(y = 0; y < M && is3div; y++)
is3div &= arrin[y][x]%3;//если есть элемент, делящийся на 3 без остатка, то обнуляем

z = 0;// число элементов в новом одномерном списке
if(is3div)
for( x = 0, z = 0; x < N; x++)
for( y = 0; y < M; y++)
if(arrin[y][x] > 0){
arrout[z] = arrin[y][x]; z++;
}
}

Автор: t800 26 Aug 2016, 18:26

Уже собираюсь в школу, и вот подумал для одноклассников сделать урок программирования, который учит делать 2 самые простые программки: "Привет всем!" и "Калькулятор":

Урок 1 Программа Привет всем!

В терминале создаёте файл командой

Код
nano hello.cc


В редакторе вставляете следующий код

Код
// программа  'Hello World!'  

#include <iostream>

int main()
{
  std::cout << "Привет всем, это Даня! \n";
  return 0;

}


Сохраняетесь (ctrl+o). Потом в терминале даете следующую команду:

Код
g++ hello.cc -o hello


Потом запускаете программу командой

Код
./hello


Урок 2 программа калькулятор

В терминале создаёте файл командой

Код
nano kakul.cc


В редакторе вставляете следующий код

Код
#include <stdio.h>



int main(void)

{

float num1;

float num2;

char op;

printf("Первое число: ");

scanf("%f",&num1);

printf("Второе число: ");

scanf("%f",&num2);

printf("Оператор ( + - * / ): ");

while ((op = getchar()) != EOF)

{

if (op == '+')

{

printf("%6.2f\n",num1 + num2);

break;

}

else if(op == '-')

{

printf("%6.2f\n",num1 - num2);

break;

}

else if(op == '*')

{

printf("%6.2f\n",num1 * num2);

break;

}

else if(op == '/')

{

if(num2 == 0)

{

printf("Ошибка: деление на ноль!\n");

break;

}

else

{

printf("%6.2f\n",num1 / num2);

break;

}

}

}

return 0;

}


Сохраняетесь (ctrl+o). Потом в терминале даете следующую команду:

Код
g++ kakul.cc -o kakul


Потом запускаете программу командой

Код
./kakul




Автор: Эроласт 26 Aug 2016, 21:36

Что за хрень с форматированием? Где табуляция, и зачем эти пустые строки после каждой операции?
И зачем писать код через консоль, и уж тем более в nano? Ты хочешь отбить желание программировать у однаклассников, чтобы конкурентов не было?)

И да, что такое "op" и почему "какил"?

Автор: feanor 26 Aug 2016, 21:46

Гнусный извращенец.
Одноклассникам - только IDE (и под винду, ага), что-нибудь нетяжелое типа CodeBlocks.
И да, в конце мейна - getchar() или что там сейчас ставят, мне когда-то непонимание, как сделать задержку после вывода серьезно отравило интерес к десктопам (и я продолжил клепать гуевые говноутилитки для мобил, доо)

Автор: tolich 26 Aug 2016, 22:16

Цитата(Эроласт @ 26 Aug 2016, 21:36) *
почему "какил"?
Не какил, а Какул. Это город такой в Пакистане.
Цитата(Эроласт @ 26 Aug 2016, 21:36) *
что такое "op"?
Сокращение от 'operation' или 'operator'.

Автор: Эроласт 27 Aug 2016, 10:04

Цитата
Сокращение от 'operation' или 'operator'.

Не умничай) Я-то понял, а вот одноклассники не поймут.
Я к тому, что в приличном обществе названия переменных полностью записывают (исключение - редкие устоявшиеся кейсы вроде let i = 0; i < 10; i++).

Автор: tolich 27 Aug 2016, 10:19

Сейчас в БД одного нашего проекта слово method в именах полей сокращено до meth. Вот это непонятно и даже смешно. А op - устоявшееся сокращение.

Автор: t800 27 Aug 2016, 12:03

Цитата(feanor @ 27 Aug 2016, 00:46) *
Гнусный извращенец.
Одноклассникам - только IDE (и под винду, ага), что-нибудь нетяжелое типа CodeBlocks.
И да, в конце мейна - getchar() или что там сейчас ставят, мне когда-то непонимание, как сделать задержку после вывода серьезно отравило интерес к десктопам (и я продолжил клепать гуевые говноутилитки для мобил, доо)


Не знаю. СоdeBlocks слишком сложный. Я когда его поставил просто испугался. Куча непонятныйх надписей и настроек и вообще я не для чего он нужет этот CodeBlockes если он даже fheroes2 собрать не смог. Заругался что не умеет работать с make файлами. В терминале игра одной командой собирается а СоdeBlockes ее собрать не может. Кому он такой нужем ? stop.gif И с другими исходниками попробовал тоже самое. В терминале собираются а в IDE даже тетрис не собрался. Пришлось командами собирать.




Автор: t800 27 Aug 2016, 14:08

Программирование на C++ (Урок 3)

Дейлаем Русский Тетрис-Черепочки на свободных исходниках.

Для этого понадобится.

1) Компилятор g++ 4.7
2) Cmake 2.8.12
3) Любой текcтовый редактор

Во первых, качаем исходники обычной игры Тетрис (анлийская версия)

https://github.com/Teyu/Tetris-SDL-game


2) Разархивируем куда нибудь


3) Создаем папку tetris

Код
mkdir tetris


Переходим в папку tetris

Код
cd tetris


И cmake собираем make файл скачаных исходников

Код
cmake ~/Tetris-SDL-game-master


затем даем команду

Код
make


собираем игру

И запускаем ее командой

Код
./Tetris


Игра всем хороша с небольшим исключением. Во-первых все по английски. А во-вторых какая-то скучаная.
Давайте сделаем ее по русский и слегка повеселей.

Делаем по русски.

Для этого открываем в редакторе файл Framework.cpp
(вот этот https://github.com/Teyu/Tetris-SDL-game/blob/master/src/Framework.cpp )

Ищем в нем строки

Код
m_ptext_points = TTF_RenderText_Solid(font, "Points: ", text_color);
    m_ptext_level = TTF_RenderText_Solid(font, "Level: ", text_color);
m_ptext_lines = TTF_RenderText_Solid(font, "Lines: ", text_color);



И изменям их на

Код
m_ptext_points = TTF_RenderUTF8_Solid(font, "Очки: ", text_color);
m_ptext_level = TTF_RenderUTF8_Solid(font, "Уровень: ", text_color);
m_ptext_lines = TTF_RenderUTF8_Solid(font, "Слои черепов: ", text_color);



Так же меням размер шрифтов строку

Код
font = TTF_OpenFont("FreeSans.ttf", 24);


меняем на

Код
font = TTF_OpenFont("FreeSans.ttf", 20);


Сохраняем файл (Ctrl-O)

и собираем игру командой

Код
make



Игра стала по русски, но все равно скучная, поэтому скачиваем архив с черепочками

Вот он http://wiki.kvkozyrev.org/uroki/Skulls.zip

И разархивируем его в папку ~/tetris/data

И игра у нас стала русской и веселой!



Домашнее задание к Уроку 3.

Вставить в игру Тетрис-Черепочки задним фоном какую-нибудь веселую картинку barb_metal.gif barb_metal.gif barb_metal.gif

Автор: tolich 27 Aug 2016, 14:27

Цитата(t800 @ 27 Aug 2016, 12:03) *
В терминале игра одной командой собирается а СоdeBlockes ее собрать не может.
Вот так и вырастают в красноглазиков.

Автор: feanor 27 Aug 2016, 15:36

На самом деле таки да, вопрос в цели.
Если "смотрите, чему я научился" - то ради бога, хозяин-барин.
Если "я хочу вас научить" - то лучше все же не бить людей лбом о порог вхождения.

Автор: t800 27 Aug 2016, 16:05

Цитата(feanor @ 27 Aug 2016, 18:36) *
На самом деле таки да, вопрос в цели.
Если "смотрите, чему я научился" - то ради бога, хозяин-барин.
Если "я хочу вас научить" - то лучше все же не бить людей лбом о порог вхождения.



Почему бить лбом? Редатор текстов знают все. Выучить команду g++ и команду make и сделать по инструкции много проще чем разобраться с настройкой непонятной IDE, потому что никто не ошибется.


IDE много сложней и непонятней чем команды. У меня что-то смогла собрать только одна IDE - Anjuta но она собирает только под Linux. СоdeBlokes вообще не умеет работать с make файлами и работает только со своим каким то cbp под Windows пришлось тоже собирать из консоли MinWG, а редактировать в WordPad. Еще я пробовал поставить Android Developer Studio но она у мне просто зависла протому что ей не хватило памяти. Поэтому для Аdroind я игру собрал тоже из терминала и в три команды

Код
./changeAppSettings.sh -a
android update project -p project -t android-23
./build.sh


И без всяких студий че три часа ставяться а потом виснут fp3.gif Может для сложных программ студия и нужна но для простой программы командой много раз проще, потому что не ошибешься и не надо в чемто непонятном еще разбираться. Надо просто написать команду как она написана и ВСЕ!

Автор: t800 09 Oct 2016, 21:07

Программирование на C++ (Урок 5) Делаем ЧАТ.

Чтобы сделать ЧАТ нам понадобится код сервера


Код
#include <iostream>
#include <cstdlib>
#include <string>

#include <SDL_net.h>

using namespace std;

const unsigned short PORT        = 1234;            // The port our server will listen for incoming connecions on
const unsigned short BUFFER_SIZE = 512;             // Size of our message buffer
const unsigned short MAX_SOCKETS = 4;               // Max number of sockets
const unsigned short MAX_CLIENTS = MAX_SOCKETS - 1; // Max number of clients in our socket set (-1 because server's listening socket takes the 1st socket in the set)

// Messages to send back to any connecting client to let them know if we can accept the connection or not
const string SERVER_NOT_FULL = "OK";
const string SERVER_FULL     = "FULL";

int main(int argc, char **argv)
{
    IPaddress serverIP;                  // The IP of the server (this will end up being 0.0.0.0 - which means roughly "any IP address")
    TCPsocket serverSocket;              // The server socket that clients will use to connect to us
    TCPsocket clientSocket[MAX_CLIENTS]; // An array of sockets for the clients, we don't include the server socket (it's specified separately in the line above)
    bool      socketIsFree[MAX_CLIENTS]; // An array of flags to keep track of which client sockets are free (so we know whether we can use the socket for a new client connection or not)

    char buffer[BUFFER_SIZE];            // Array of characters used to store the messages we receive
    int receivedByteCount = 0;           // A variable to keep track of how many bytes (i.e. characters) we need to read for any given incoming message i.e. the size of the incoming data

    int clientCount = 0;                 // Count of how many clients are currently connected to the server

    bool shutdownServer = false;         // Flag to control when to shut down the server

    // Initialise SDL_net (Note: We don't initialise or use normal SDL at all - only the SDL_net library!)
    if (SDLNet_Init() == -1)
    {
        cout << "Failed to intialise SDL_net: " << SDLNet_GetError() << endl;
        exit(-1); // Quit!
    }

    // Create the socket set with enough space to store our desired number of connections (i.e. sockets)
    SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(MAX_SOCKETS);
    if (socketSet == NULL)
    {
        cout << "Failed to allocate the socket set: " << SDLNet_GetError() << "\n";
        exit(-1); // Quit!
    }
    else
    {
        cout << "Allocated socket set with size:  " << MAX_SOCKETS << ", of which " << MAX_CLIENTS << " are availble for use by clients." <<  endl;
    }

    // Initialize all the client sockets (i.e. blank them ready for use!)
    for (int loop = 0; loop < MAX_CLIENTS; loop++)
    {
        clientSocket[loop] = NULL;
        socketIsFree[loop] = true; // Set all our sockets to be free (i.e. available for use for new client connections)
    }

    // Try to resolve the provided server hostname. If successful, this places the connection details in the serverIP object and creates a listening port on the provided port number
    // Note: Passing the second parameter as "NULL" means "make a listening port". SDLNet_ResolveHost returns one of two values: -1 if resolving failed, and 0 if resolving was successful
    int hostResolved = SDLNet_ResolveHost(&serverIP, NULL, PORT);

    if (hostResolved == -1)
    {
        cout << "Failed to resolve the server host: " << SDLNet_GetError() << endl;
    }
    else // If we resolved the host successfully, output the details
    {
        // Get our IP address in proper dot-quad format by breaking up the 32-bit unsigned host address and splitting it into an array of four 8-bit unsigned numbers...
        Uint8 * dotQuad = (Uint8*)&serverIP.host;

        //... and then outputting them cast to integers. Then read the last 16 bits of the serverIP object to get the port number
        cout << "Successfully resolved server host to IP: " << (unsigned short)dotQuad[0] << "." << (unsigned short)dotQuad[1] << "." << (unsigned short)dotQuad[2] << "." << (unsigned short)dotQuad[3];
        cout << " port " << SDLNet_Read16(&serverIP.port) << endl << endl;
    }

    // Try to open the server socket
    serverSocket = SDLNet_TCP_Open(&serverIP);

    if (!serverSocket)
    {
        cout << "Failed to open the server socket: " << SDLNet_GetError() << "\n";
        exit(-1);
    }
    else
    {
        cout << "Sucessfully created server socket." << endl;
    }

    // Add our server socket to the socket set
    SDLNet_TCP_AddSocket(socketSet, serverSocket);

    cout << "Awaiting clients..." << endl;

    // Main loop...
    do
    {
        // Check for activity on the entire socket set. The second parameter is the number of milliseconds to wait for.
        // For the wait-time, 0 means do not wait (high CPU!), -1 means wait for up to 49 days (no, really), and any other number is a number of milliseconds, i.e. 5000 means wait for 5 seconds
        int numActiveSockets = SDLNet_CheckSockets(socketSet, 0);

        if (numActiveSockets != 0)
        {
            cout << "There are currently " << numActiveSockets << " socket(s) with data to be processed." << endl;
        }

        // Check if our server socket has received any data
        // Note: SocketReady can only be called on a socket which is part of a set and that has CheckSockets called on it (the set, that is)
        // SDLNet_SocketRead returns non-zero for activity, and zero is returned for no activity. Which is a bit bass-ackwards IMHO, but there you go.
        int serverSocketActivity = SDLNet_SocketReady(serverSocket);

        // If there is activity on our server socket (i.e. a client has trasmitted data to us) then...
        if (serverSocketActivity != 0)
        {
            // If we have room for more clients...
            if (clientCount < MAX_CLIENTS)
            {

                // Find the first free socket in our array of client sockets
                int freeSpot = -99;
                for (int loop = 0; loop < MAX_CLIENTS; loop++)
                {
                    if (socketIsFree[loop] == true)
                    {
                        //cout << "Found a free spot at element: " << loop << endl;
                        socketIsFree[loop] = false; // Set the socket to be taken
                        freeSpot = loop;            // Keep the location to add our connection at that index in the array of client sockets
                        break;                      // Break out of the loop straight away
                    }
                }

                // ...accept the client connection and then...
                clientSocket[freeSpot] = SDLNet_TCP_Accept(serverSocket);

                // ...add the new client socket to the socket set (i.e. the list of sockets we check for activity)
                SDLNet_TCP_AddSocket(socketSet, clientSocket[freeSpot]);

                // Increase our client count
                clientCount++;

                // Send a message to the client saying "OK" to indicate the incoming connection has been accepted
                strcpy( buffer, SERVER_NOT_FULL.c_str() );
                int msgLength = strlen(buffer) + 1;
                SDLNet_TCP_Send(clientSocket[freeSpot], (void *)buffer, msgLength);

                cout << "Client connected. There are now " << clientCount << " client(s) connected." << endl << endl;
            }
            else // If we don't have room for new clients...
            {
                cout << "*** Maximum client count reached - rejecting client connection ***" << endl;

                // Accept the client connection to clear it from the incoming connections list
                TCPsocket tempSock = SDLNet_TCP_Accept(serverSocket);

                // Send a message to the client saying "FULL" to tell the client to go away
                strcpy( buffer, SERVER_FULL.c_str() );
                int msgLength = strlen(buffer) + 1;
                SDLNet_TCP_Send(tempSock, (void *)buffer, msgLength);

                // Shutdown, disconnect, and close the socket to the client
                SDLNet_TCP_Close(tempSock);
            }

        } // End of if server socket is has activity check

        // Loop to check all possible client sockets for activity
        for (int clientNumber = 0; clientNumber < MAX_CLIENTS; clientNumber++)
        {
            // If the socket is ready (i.e. it has data we can read)... (SDLNet_SocketReady returns non-zero if there is activity on the socket, and zero if there is no activity)
            int clientSocketActivity = SDLNet_SocketReady(clientSocket[clientNumber]);

            //cout << "Just checked client number " << clientNumber << " and received activity status is: " << clientSocketActivity << endl;

            // If there is any activity on the client socket...
            if (clientSocketActivity != 0)
            {
                // Check if the client socket has transmitted any data by reading from the socket and placing it in the buffer character array
                receivedByteCount = SDLNet_TCP_Recv(clientSocket[clientNumber], buffer, BUFFER_SIZE);

                // If there's activity, but we didn't read anything from the client socket, then the client has disconnected...
                if (receivedByteCount <= 0)
                {
                    //...so output a suitable message and then...
                    cout << "Client " << clientNumber << " disconnected." << endl << endl;

                    //... remove the socket from the socket set, then close and reset the socket ready for re-use and finally...
                    SDLNet_TCP_DelSocket(socketSet, clientSocket[clientNumber]);
                    SDLNet_TCP_Close(clientSocket[clientNumber]);
                    clientSocket[clientNumber] = NULL;

                    // ...free up their slot so it can be reused...
                    socketIsFree[clientNumber] = true;

                    // ...and decrement the count of connected clients.
                    clientCount--;

                    cout << "Server is now connected to: " << clientCount << " client(s)." << endl << endl;
                }
                else // If we read some data from the client socket...
                {
                    // Output the message the server received to the screen
                    cout << "Received: >>>> " << buffer << " from client number: " << clientNumber << endl;

                    // Send message to all other connected clients
                    int originatingClient = clientNumber;

                    for (int loop = 0; loop < MAX_CLIENTS; loop++)
                    {
                        // Send a message to the client saying "OK" to indicate the incoming connection has been accepted
                        //strcpy( buffer, SERVER_NOT_FULL.c_str() );
                        int msgLength = strlen(buffer) + 1;

                        // If the message length is more than 1 (i.e. client pressed enter without entering any other text), then
                        // send the message to all connected clients except the client who originated the message in the first place
                        if (msgLength > 1 && loop != originatingClient && socketIsFree[loop] == false)
                        {
                            cout << "Retransmitting message: " << buffer << " (" << msgLength << " bytes) to client number: " << loop << endl;
                            SDLNet_TCP_Send(clientSocket[loop], (void *)buffer, msgLength);
                        }

                    }

                    // If the client told us to shut down the server, then set the flag to get us out of the main loop and shut down
                    if ( strcmp(buffer, "shutdown") == 0 )
                    {
                        shutdownServer = true;

                        cout << "Disconnecting all clients and shutting down the server..." << endl << endl;
                    }

                }

            } // End of if client socket is active check

        } // End of server socket check sockets loop

    }
    while (shutdownServer == false); // End of main loop

    // Free our socket set (i.e. all the clients in our socket set)
    SDLNet_FreeSocketSet(socketSet);

    // Close our server socket, cleanup SDL_net and finish!
    SDLNet_TCP_Close(serverSocket);

    SDLNet_Quit();

    return 0;
}


Cобирать надо такой командой :

Код
g++ server.cc -w -lSDL_net -o server



И код клинета


Код
// Includes for non-blocking keyboard input
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <termios.h> // If we do not include termios.h the client WILL compile but it WILL NOT WORK!
#include <unistd.h>
#include <fcntl.h>

#include <iostream>
#include <string>

#include <SDL_net.h>

using namespace std;

const unsigned short PORT        = 1234; // The port we are connecting to
const unsigned short BUFFER_SIZE = 512;  // Size of our message buffer (i.e. maximum length of characters in a message)

struct termios orig_termios;

// Function to reset the terminal to blocking mode
void reset_terminal_mode()
{
    tcsetattr(0, TCSANOW, &orig_termios);
}

// Sets the terminal mode to conio mode
void set_conio_terminal_mode()
{
    struct termios new_termios;

    // Take two copies - one for now, one for later
    tcgetattr(0, &orig_termios);
    memcpy(&new_termios, &orig_termios, sizeof(new_termios));

    // register cleanup handler, and set the new terminal mode
    //atexit(reset_terminal_mode); // Commented out because I switch and swap terminal modes a lot - just remember to call reset_terminal_mode() when we finish up
    cfmakeraw(&new_termios);
    tcsetattr(0, TCSANOW, &new_termios);
}

// Fuction to check if a key has been pressed
int kbHit()
{
    // How long to wait for input
    // Note: As soon as we get input the wait is immediately over - so it's not like our typing rate is limited in any way!
    long waitSeconds      = 1L;
    long waitMicroSeconds = 0L;
    struct timeval tv = { waitSeconds, waitMicroSeconds };

    // Create a file descriptor set
    fd_set fds;

    FD_SET(0, &fds);
    return select(1, &fds, NULL, NULL, &tv);
}

// Function to read the contents of the keypress
int getch()
{
    int r;
    unsigned char c;
    if ((r = read(0, &c, sizeof(c))) < 0)
    {
        //cout << "About to return a number..." << endl;
        return r;
    }
    else
    {
        //cout << "About to return a character..." << endl;
        return c;
    }
}

int main(int argc, char **argv)
{
    const char *host;         // Where we store the host name

    IPaddress serverIP;       // The IP we will connect to
    TCPsocket clientSocket;   // The socket to use
    string    serverName;     // The server name

    string userInput = "";    // A string to hold our user input
    int inputLength  = 0;     // The length of our string in characters
    char buffer[BUFFER_SIZE]; // Array of character's we'll use to transmit our message. We get input into the userInput string for ease of use, then just copy it to this character array and send it.

    // Initialise SDL_net
    if (SDLNet_Init() < 0)
    {
        cout << "Failed to intialise SDN_net: " << SDLNet_GetError() << "\n";
        exit(-1); // Quit!
    }

    // Ask the user for a server to connect to - can be entered as a hostname (i.e. localhost etc.) or an IP address (i.e. 127.0.0.1 etc.)
    cout << "Server Name: ";
    //getline(cin, serverName); // Uncomment this and remove the below line to change the server we're connecting to...
    serverName = "localhost";

    // Create the socket set with enough space to store our desired number of connections (i.e. sockets)
    SDLNet_SocketSet socketSet = SDLNet_AllocSocketSet(1);
    if (socketSet == NULL)
    {
        cout << "Failed to allocate the socket set: " << SDLNet_GetError() << "\n";
        exit(-1); // Quit!
    }
    else
    {
        cout << "Successfully allocated socket set." << endl;
    }

    // Try to resolve the host. If successful, this places the connection details in the serverIP object
    int hostResolved = SDLNet_ResolveHost(&serverIP, serverName.c_str(), PORT);

    if (hostResolved == -1)
    {
        cout << "Failed to resolve the server hostname: " << SDLNet_GetError() << "\nContinuing...\n";
    }
    else // If we successfully resolved the host then output the details
    {
        // Get our IP address in proper dot-quad format by breaking up the 32-bit unsigned host address and splitting it into an array of four 8-bit unsigned numbers...
        Uint8 * dotQuad = (Uint8*)&serverIP.host;

        //... and then outputting them cast to integers. Then read the last 16 bits of the serverIP object to get the port number
        cout << "Successfully resolved host to IP: " << (unsigned short)dotQuad[0] << "." << (unsigned short)dotQuad[1] << "." << (unsigned short)dotQuad[2] << "." << (unsigned short)dotQuad[3];
        cout << " port " << SDLNet_Read16(&serverIP.port) << endl << endl;
    }

    // Try to resolve the IP of the server, just for kicks
    if ((host = SDLNet_ResolveIP(&serverIP)) == NULL)
    {
        cout << "Failed to resolve the server IP address: " << SDLNet_GetError() << endl;
    }
    else
    {
        cout << "Successfully resolved IP to host: " << host << endl;
    }

    // Flag to keep track of when to disconnect and finish up. We initially set it so that we CANNOT connect, and only change this to false when we got an "OK" response from the server
    bool shutdownClient = true;

    // Try to open a connection to the server and quit out if we can't connect
    clientSocket = SDLNet_TCP_Open(&serverIP);
    if (!clientSocket)
    {
        cout << "Failed to open socket to server: " << SDLNet_GetError() << "\n";
        exit(-1);
    }
    else // If we successfully opened a connection then check for the server response to our connection
    {
        cout << "Connection okay, about to read connection status from the server..." << endl;

        // Add our socket to the socket set for polling
        SDLNet_TCP_AddSocket(socketSet, clientSocket);

        // Wait for up to five seconds for a response from the server
        // Note: If we don't check the socket set and WAIT for the response, we'll be checking before the server can respond, and it'll look as if the server sent us nothing back
        int activeSockets = SDLNet_CheckSockets(socketSet, 5000);

        cout << "There are " << activeSockets << " socket(s) with data on them at the moment." << endl;

        // Check if we got a response from the server
        int gotServerResponse = SDLNet_SocketReady(clientSocket);

        if (gotServerResponse != 0)
        {
            cout << "Got a response from the server... " << endl;
            int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, buffer, BUFFER_SIZE);

            cout << "Got the following from server: " << buffer << "(" << serverResponseByteCount << " bytes)" << endl;

            // We got an okay from the server, so we can join!
            if ( strcmp(buffer, "OK") == 0 )
            {
                // So set the flag to say we're not quitting out just yet
                shutdownClient = false;

                cout << "Joining server now..." << endl << endl;
            }
            else
            {
                cout << "Server is full... Terminating connection." << endl;
            }
        }
        else
        {
            cout << "No response from server..." << endl;
        }

    } // End of if we managed to open a connection to the server condition

    bool wrotePrompt = false; // Whether or not we've already written the prompt
    bool sendMessage = false; // Whether or not it's time to send the message (flips to true when the user presses return)

    // While it's not time to shutdown the client...
    while (shutdownClient == false)
    {
        // Write the prompt only once per line of input. This gets reset so that it's displayed again after a message is sent
        if (wrotePrompt == false)
        {
            cout << "Write something:" << endl;
            wrotePrompt = true;
        }

        // If we've detected that the user has pressed a key..
        set_conio_terminal_mode();
        int status = kbHit();
        reset_terminal_mode();

        //cout << "status is: " << status << endl;

        if (status != 0)
        {
            //cout << "key was pressed and status is" << status << endl;

            // Get the keypress
            set_conio_terminal_mode();
            char theChar = getch();
            reset_terminal_mode();

            // Output the character to stdout
            cout << theChar;

            // Flush the character to the screen
            fflush(stdout);

            // If the keypressed wasn't return then add the character to our message string
            if ((int)theChar != 13)
            {
                //cout << "Got the character: " << theChar << " (which is number: " << int(theChar) << ")" << endl;

                // Add the character to our input string
                userInput += theChar;
            }
            else // Otherwise (if the user pressed enter) then send the message
            {
                //cout << "user pressed return" << endl;

                // Copy our user's string into our char array called "buffer"
                strcpy( buffer, userInput.c_str() );

                // Calculate the length of our input and then add 1 (for the terminating character) to get the total number of characters we need to send
                inputLength = strlen(buffer) + 1;

                // Send the message to the server
                if (SDLNet_TCP_Send(clientSocket, (void *)buffer, inputLength) < inputLength)
                {
                    cout << "Failed to send message: " << SDLNet_GetError() << endl;
                    exit(-1);
                }
                else
                {
                    //cout << "Message sent successfully." << endl;

                    // If we've asked the server to shutdown or we want out then set the flag appropriately
                    if (sendMessage == true && (userInput == "quit" || userInput == "exit" || userInput == "shutdown"))
                    {
                        shutdownClient = true;
                    }

                    // Reset for the next message
                    cout << endl;
                    wrotePrompt = false;
                    sendMessage = false;
                    userInput = "";
                }

            } // End of message sending section

        } // End of if the user pressed a key test

        // Check our socket set for activity. Don't wait if there's nothing on the socket just continue
        int socketActive = SDLNet_CheckSockets(socketSet, 0);

        //cout << "Sockets with data on them at the moment: " << activeSockets << endl;

        if (socketActive != 0)
        {
            // Check if we got a response from the server
            int messageFromServer = SDLNet_SocketReady(clientSocket);

            if (messageFromServer != 0)
            {
                //cout << "Got a response from the server... " << endl;
                int serverResponseByteCount = SDLNet_TCP_Recv(clientSocket, buffer, BUFFER_SIZE);

                cout << "Received: " << buffer << endl;// "(" << serverResponseByteCount << " bytes)" << endl;

                if (strcmp(buffer, "shutdown") == 0)
                {
                    cout << "Server is going down. Disconnecting..." << endl;
                    shutdownClient = true;
                }
            }
            else
            {
                //cout << "No response from server..." << endl;
            }

        } // End of if socket has activity check

    } // End of main while loop

    // Close our socket, cleanup SDL_net, reset the terminal mode and finish!
    SDLNet_TCP_Close(clientSocket);

    SDLNet_Quit();

    reset_terminal_mode();

    return 0;
}


Собирать надо такой командой

Код
g++ client.cc -w -lSDL_net -o client


И получаем вот такой ЧАТ


Автор: Эроласт 10 Oct 2016, 11:17

Какой же лютый трындец. Неужели нельзя взять уже готовую высокоуровневую обертку? Не поверю, что для си++ нет такой.

Автор: t800 10 Oct 2016, 15:16

Цитата(Эроласт @ 10 Oct 2016, 14:17) *
Какой же лютый трындец. Неужели нельзя взять уже готовую высокоуровневую обертку? Не поверю, что для си++ нет такой.


Ну я нагуглил исходники программы которая может посылать e-mail и умеет работать с SDL_net
называется она SDLmail правда она только текст умеет посылать (как и curl) то есть для атачмента
надо еще base64 делать, вот он эта программа:


Автор: FBX 11 Oct 2016, 03:45

Цитата
Код
using namespace std;

Ну сколько можно…

Автор: t800 11 Oct 2016, 07:25

Цитата(FBX @ 11 Oct 2016, 06:45) *
Цитата
Код
using namespace std;

Ну сколько можно…


Ну я счас для интереса попробовал изменить на

Код
using namespace fbx;


g++ сильно заругался.
Код
danya@danya:~/hello$ g++ server.cc -w -lSDL_net -o server
server.cc:9:17: ошибка: «fbx» is not a namespace-name
server.cc:9:20: ошибка: expected namespace-name before «;» token
server.cc:17:7: ошибка: «string» не является именем типа
server.cc:18:7: ошибка: «string» не является именем типа
server.cc: В функции «int main(int, char**)»:
server.cc:37:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:37:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:37:73: ошибка: нет декларации «endl» в этой области видимости
server.cc:37:73: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:45:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:45:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:50:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:50:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:50:143: ошибка: нет декларации «endl» в этой области видимости
server.cc:50:143: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:66:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:66:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:66:79: ошибка: нет декларации «endl» в этой области видимости
server.cc:66:79: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:74:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:74:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:75:62: ошибка: нет декларации «endl» в этой области видимости
server.cc:75:62: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:83:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:66:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:66:79: ошибка: нет декларации «endl» в этой области видимости
server.cc:66:79: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:74:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:74:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:75:62: ошибка: нет декларации «endl» в этой области видимости
server.cc:75:62: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:83:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:83:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:88:9: ошибка: нет декларации «cout» в этой области видимости
server.cc:88:9: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:88:57: ошибка: нет декларации «endl» в этой области видимости
server.cc:88:57: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:94:5: ошибка: нет декларации «cout» в этой области видимости
server.cc:94:5: замечание: suggested alternative:
/usr/include/c++/4.6/iostream:62:18: замечание:   «std::cout»
server.cc:94:38: ошибка: нет декларации «endl» в этой области видимости
server.cc:94:38: замечание: suggested alternative:
/usr/include/c++/4.6/ostream:543:5: замечание:   «std::endl»
server.cc:143:33: ошибка: нет декларации «SERVER_NOT_FULL» в этой области видимости
server.cc:157:33: ошибка: нет декларации «SERVER_FULL» в этой области видимости

Автор: Эроласт 11 Oct 2016, 14:36


Вот к чему приводит бездумное копирование кода из гугла в блокнот. Чувак даже не знает, что значит та или иная строка. А ещё уроки пишет.
Хорошо хоть не по майнкрафту.

Автор: t800 11 Oct 2016, 15:07

Цитата(Эроласт @ 11 Oct 2016, 17:36) *

Вот к чему приводит бездумное копирование кода из гугла в блокнот. Чувак даже не знает, что значит та или иная строка. А ещё уроки пишет.
Хорошо хоть не по майнкрафту.


Почему бездумное? Я же копирую не любой код а который нахожу по нужным мне запросам. Например мне нужно оправить e-mail и я гугулю запрос "код C++ SDL_net отправить e-mail " а про строку что она значит по моему самый простой способ понять что она делает это вставить ее в программу и посмотреть что она делает. Вот я вставил строчку

Код
using namespace fbx;


И увидел что она делает. Она делает ошибки. Значит это строчка не правильная! А правильная строчка вот такая:

Код
using namespace std;


Потому что с ней программа работает.

Автор: AlexSpl 11 Oct 2016, 22:18

Цитата
И увидел что она делает. Она делает ошибки.

Если в коде ошибки, его лучше закомментировать от греха подальше:

Код
// using namespace fbx;


Потом запускаешь программу, которая генерит набор символов заданной длины в лексикографическом порядке (например, "usign namespcae fеr;", "singu spaceamen sdt;" и т.д.) и комментишь неудачные варианты. Спустя конечное время обязательно должен получиться вариант, который скомпилируется.

Автор: feanor 11 Oct 2016, 22:27

Срочно, срочно учебник.
Мне для сишки когда-то очень зашел полуучебник-полусправочник Шилдта (по нему и учился, когда K&R еще советского издания отдал владельцу). Он и для С++ писал - вот его не читал, не знаю, но думаю - тоже вполне годнота для начала.
Герберт Шилдт, "Полный справочник по С++".

Автор: AlexSpl 11 Oct 2016, 22:44

Как поётся в одной старой песне: "Поймём потом, поймём потом"

https://www.youtube.com/watch?v=2KW3roDj3RI

Автор: tolich 12 Oct 2016, 01:21

Также неплохо попробовать другие варианты:

Код
using deep space nine;
tossing whole place down;
mocking to face a clown;
Вариантов нереально много.

Автор: t800 12 Oct 2016, 16:46

Цитата(AlexSpl @ 12 Oct 2016, 01:18) *
Цитата
И увидел что она делает. Она делает ошибки.

Если в коде ошибки, его лучше закомментировать от греха подальше:

Код
// using namespace fbx;



Я так и делаю


Цитата
Потом запускаешь программу, которая генерит набор символов заданной длины в лексикографическом порядке (например, "usign namespcae fеr;", "singu spaceamen sdt;" и т.д.) и комментишь неудачные варианты. Спустя конечное время обязательно должен получиться вариант, который скомпилируется.


А вот это не правильно! Надо просто посмотреть в Google что за ошибка. И вставить тот код который написано что надо вставлять при таких ошибках. И тогда получается намного быстрее.

Кстат вот! Вот код исходника что делает base64 кодирование.

Код
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include "base64.h"
#include <cstring>


int main() {

//    char *FileBuf = NULL;
    FILE* hFile = NULL;
    unsigned long int FileSize,TotalSize;
//    char *SendBuf = NULL;
    unsigned int q, i,res;
        hFile = fopen("input.txt","rb");

        if(hFile == NULL)
          {
              fputs("Ошибка файла \n", stderr);
              exit(1);
              }

// Из примера


  // определяем размер файла
  fseek(hFile , 0 , SEEK_END);                          // устанавливаем позицию в конец файла
  long lSize = ftell(hFile);                            // получаем размер в байтах
  q = lSize/54+1;
  rewind (hFile);                                       // устанавливаем указатель в конец файла

  char * SendBuf = (char*) malloc(sizeof(char) * lSize);
  char * FileBuf = (char*) malloc(sizeof(char) * lSize); // выделить память для хранения содержимого файла
  if (FileBuf  == NULL)
  {
      fputs("Ошибка памяти", stderr);
      exit(2);
  }

/*  size_t result = fread(buffer, 1, lSize, hFile);       // считываем файл в буфер
//    fread(buffer,sizeof(char),54,hFile);
  if (result != lSize)
  {
      fputs("Ошибка чтения", stderr);
      exit (3);
  }

  //содержимое файла теперь находится в буфере
  puts(buffer);

  // завершение работы
  fclose (hFile);
  free (buffer);

// Конец  из примера

          
*/

// Проверяем размер:

// FileSize = 0;
//        while(!feof(hFile))
//            FileSize += fread(FileBuf,sizeof(char),54,hFile);
//        TotalSize += FileSize;
// sending the file:
//        if(TotalSize/1024 > MSG_SIZE_IN_MB*1024)
//            throw ECSmtp(ECSmtp::MSG_TOO_BIG);
//        else
//        {
//            fseek (hFile,0,SEEK_SET);
//            MsgPart = 0;
//            for(i=0;i<FileSize/54+1;i++)
//            {
//        res = fread(FileBuf,sizeof(char),54,hFile);
//
//MsgPart ? strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*(FileBuf),res).c_str()):              : //strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*(FileBuf),res).c_str());
//                strcat(SendBuf,"\r\n");
//                MsgPart += res + 2;
//        if(MsgPart >= BUFFER_SIZE/2)
//        {
// sending part of the message
//                    MsgPart = 0;
//                    SendData(); // FileBuf, FileName, fclose(hFile);
//                }
//            }
//            if(MsgPart)
//            {
//                SendData(); // FileBuf, FileName, fclose(hFile);
//            }
// }
//    fclose(hFile);
//    }
//    delete[] FileBuf;
//    delete[] FileName;


        FileSize = 0;
        while(!feof(hFile))
        {
        FileSize = fread(FileBuf,sizeof(char),54,hFile);
//        std::cout << "FileSize равно="  << FileSize << "\r\n";
//         TotalSize += FileSize;
//              std::cout << "TotalSize равно=" << TotalSize << "\r\n";
        }
        // Делаем буфер:
        fseek (hFile,0,SEEK_SET);
//        std::cout << "TotalSize равно=" << TotalSize << "\r\n";
//        std::cout << "FileSize равно=" << FileSize << "\r\n";
//        std::cout << "lSize равно=" << lSize << "\r\n";
//        std::cout << "q равно=" << q << "\r\n";
            for(i=0;i<q;i++)
{        res = fread(FileBuf,sizeof(char),54,hFile);
//        std::cout << "i равно =" << i << "\r\n";
        strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),54).c_str());
//        strcat(SendBuf,"ПРИВЕТ  ЭТО ДАНЯ!!!!!\r\n");
            strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcat(SendBuf,"\r");
//        puts(SendBuf);

//        std::cout << "RES равно=" << res << "\r\n";
            if(SendBuf)
        {
                puts(SendBuf);
//                FILE * ptrFile = fopen ( "output.txt" , "wb" );
//                fwrite(SendBuf, 1 , sizeof(SendBuf) , ptrFile ); // записать в файл содержимое буфера
//                fclose (ptrFile);
//                fclose(hFile);
            }
}
    return 0;
}



Собрал его из трех разных правда он еще в файл писать не может, приходится его вот так запускать

Код
./test > test.txt


Но кодирует уже правильно. barb_metal.gif barb_metal.gif barb_metal.gif

Автор: t800 12 Oct 2016, 20:14

Фух заработало! barb_metal.gif barb_metal.gif barb_metal.gif
И вот что у меня получилось:

Код
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include "base64.h"
#include <cstring>


int main() {

    FILE* hFile = NULL;
    unsigned int q, i,res;
        hFile = fopen("input.txt","rb");

        if(hFile == NULL)
          {
              fputs("Ошибка файла \n", stderr);
              exit(1);
              }

  // определяем размер файла
  fseek(hFile , 0 , SEEK_END);                          // устанавливаем позицию в конец файла
  long lSize = ftell(hFile);                            // получаем размер в байтах
  q = lSize/54+1;
  rewind (hFile);                                       // устанавливаем указатель в конец файла

  char * SendBuf = (char*) malloc(sizeof(char) * lSize);
  char * FileBuf = (char*) malloc(sizeof(char) * lSize); // выделить память для хранения содержимого файла
  if (FileBuf  == NULL)
     {
      fputs("Ошибка памяти", stderr);
      exit(2);
     }
    // Делаем буфер:
    fseek (hFile,0,SEEK_SET);
    FILE * ptrFile = fopen ( "output.txt" , "wb" );
    for(i=0;i<q;i++)
    {    res = fread(FileBuf,sizeof(char),54,hFile);
        strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
            strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcat(SendBuf,"\r");
            fputs(SendBuf, ptrFile);
    }
    fclose (ptrFile);
  return 0;
}



Автор: AlexSpl 13 Oct 2016, 02:05

Цитата
Фух заработало!

Ну и слава богу!

Автор: t800 13 Oct 2016, 06:17

Цитата(AlexSpl @ 13 Oct 2016, 05:05) *
Цитата
Фух заработало!

Ну и слава богу!



Да чуть не забыл! Чтобы код работал рядом с ним надо положить еще два файлика: base64.h и base64.cpp
и в них написать код из вот этого примера http://www.adp-gmbh.ch/cpp/common/base64.html
и собирать или камандой

Код
g++ *.cpp -o test


Или сделать вот такой make файл

Код
nano makefile


Написать в него вот такой код (я его взял от другой программы)

Код
# Automatyczny makefile

CC = g++
CFLAGS = -Wall -O2 -DLINUX
ONLYCOMPILE = $(CC) $(CFLAGS) -c -g
OBJFILES :=  $(patsubst %.cpp,%.o,$(wildcard *.cpp))
PROGNAME = test

all: $(PROGNAME)

$(PROGNAME) : $(OBJFILES)
        $(CC) -o $(PROGNAME) $(OBJFILES)

%.o: %.cpp
        ${ONLYCOMPILE} -o $@ $<

clean:
        rm *.o


И собирать камандой

Код
make

Автор: t800 14 Oct 2016, 18:58

Цитата(t800 @ 12 Oct 2016, 23:14) *
Фух заработало! barb_metal.gif barb_metal.gif barb_metal.gif
И вот что у меня получилось:

Код
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include "base64.h"
#include <cstring>


int main() {

    FILE* hFile = NULL;
    unsigned int q, i,res;
        hFile = fopen("input.txt","rb");

        if(hFile == NULL)
          {
              fputs("Ошибка файла \n", stderr);
              exit(1);
              }

  // определяем размер файла
  fseek(hFile , 0 , SEEK_END);                          // устанавливаем позицию в конец файла
  long lSize = ftell(hFile);                            // получаем размер в байтах
  q = lSize/54+1;
  rewind (hFile);                                       // устанавливаем указатель в конец файла

  char * SendBuf = (char*) malloc(sizeof(char) * lSize);
  char * FileBuf = (char*) malloc(sizeof(char) * lSize); // выделить память для хранения содержимого файла
  if (FileBuf  == NULL)
     {
      fputs("Ошибка памяти", stderr);
      exit(2);
     }
    // Делаем буфер:
    fseek (hFile,0,SEEK_SET);
    FILE * ptrFile = fopen ( "output.txt" , "wb" );
    for(i=0;i<q;i++)
    {    res = fread(FileBuf,sizeof(char),54,hFile);
        strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
            strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcat(SendBuf,"\r");
            fputs(SendBuf, ptrFile);
    }
    fclose (ptrFile);
  return 0;
}


Я вот думаю! Мне надо три файла по почте послать - autosave.sav, fheroes2.hgs и fheroes2.hgsс и получается что для кадого файла надо будет писать такой же код и он получится очень длинный. Я посмотрел как в других программах сделано, там сделано по другому делается void Send и что-то такое и потом просто в дпругой месте просто пишут это Send и именен файла который надо послать. И подумал может мне тоже так сделать? Только правильно надо этот void Send написать чтобы потому ему файлы можно было указывать?





Автор: feanor 14 Oct 2016, 19:01

СРОЧНО УЧЕБНИК

Автор: t800 15 Oct 2016, 16:38

Так ну я вроде сделал

Код
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include "base64.h"
#include <cstring>

int Send(const char *FileName)
{
unsigned int q, i,res;
FILE* hFile = NULL;    
hFile = fopen(FileName,"rb");    

        if(hFile == NULL)
          {
              fputs("Ошибка файла \n", stderr);
              exit(1);
              }

  // определяем размер файла
  fseek(hFile , 0 , SEEK_END);                          // устанавливаем позицию в конец файла
  long lSize = ftell(hFile);                            // получаем размер в байтах
  q = lSize/54+1;
  rewind (hFile);                                       // устанавливаем указатель в конец файла

  char * SendBuf = (char*) malloc(sizeof(char) * lSize);
  char * FileBuf = (char*) malloc(sizeof(char) * lSize); // выделить память для хранения содержимого файла
  char * TitleBuf = (char*) malloc(sizeof(char) * 1024);
  if (FileBuf  == NULL)
     {
      fputs("Ошибка памяти", stderr);
      exit(2);
     }
    // Делаем буфер:
    fseek (hFile,0,SEEK_SET);
    FILE * ptrFile = fopen ( "output.txt" , "ab" );
//Пишем заголовки
    strcat(TitleBuf,"\n");
    strcat(TitleBuf,"Subject: Turnir\n");
    strcat(TitleBuf,"Content-Type: multipart/mixed;\n");
    strcat(TitleBuf,"Content-Disposition: attachment;\n");
    strcat(TitleBuf,"\tfilename=autosave.sav\n");
    strcat(TitleBuf,"Content-Transfer-Encoding: base64\n");
    strcat(TitleBuf,"Content-Type: application/octet-stream;\n");
    strcat(TitleBuf,"\tname=autosave.sav\n\n");
    fputs(TitleBuf, ptrFile);
//Кодируем и пищем файл
    for(i=0;i<q;i++)
    {    
        res = fread(FileBuf,sizeof(char),54,hFile);
        strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcat(SendBuf,"\r\n");
        fputs(SendBuf, ptrFile);
        fflush (ptrFile);
    }
    //fclose (ptrFile);
  return(0);
}

int main() {
Send("autosave.sav");
Send("fheroes2.hgs");
Send("fheroes2.hgsc");
return 0;
}


И оно сейчас вроде работает но есть одна проблема.

Если в конце int Send написать как оно и полагается каманду fclose (ptrFile); то она пишет в конце в файл еще какие-то дурацкие значки. Я погуглил это называется мусор и вроде советуют вставить в код команду fflush
я ее в разные места на пробу повствалял. И оно вроде заработало нормально (мусор перестало писать) но только при условии если команда fclose (ptrFile); выключена (как это в коде сейчас), оно сейчас вроде работает но мне это нравится почему команда fclose (ptrFile); включена все равно пишет мусор.

Автор: t800 15 Oct 2016, 18:22

Фух вроде нашел правильную каманду

Код
memset(Buf, 0, sizeof(Buf));


И в результате получилось вот так

Код
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "base64.h"

int Send(const char *FileName)
{
unsigned int q, i,res;
FILE* hFile = NULL;    
hFile = fopen(FileName,"rb");    

        if(hFile == NULL)
          {
              fputs("Ошибка файла \n", stderr);
              exit(1);
              }

  // определяем размер файла
  fseek(hFile , 0 , SEEK_END);                          // устанавливаем позицию в конец файла
  long lSize = ftell(hFile);                            // получаем размер в байтах
  q = lSize/54+1;
  rewind (hFile);                                       // устанавливаем указатель в конец файла

  char * SendBuf = (char*) malloc(sizeof(char) * lSize);
  char * FileBuf = (char*) malloc(sizeof(char) * lSize); // выделить память для хранения содержимого файла
  char * TitleBuf = (char*) malloc(sizeof(char) * 1024);
  if (FileBuf  == NULL)
     {
      fputs("Ошибка памяти", stderr);
      exit(2);
     }
    // Делаем буфер:
    fseek (hFile,0,SEEK_SET);
    FILE * ptrFile = fopen ( "output.txt" , "ab" );
//Пишем заголовки
    memset(SendBuf, 0, sizeof(SendBuf)); // чистим буфер от мусора
    memset(TitleBuf, 0, sizeof(TitleBuf)); // чистим буфер от мусора
    strcat(TitleBuf,"Subject: Turnir\n");
    strcat(TitleBuf,"Content-Type: multipart/mixed;\n");
    strcat(TitleBuf,"Content-Disposition: attachment;\n");
    strcat(TitleBuf,"\tfilename=autosave.sav\n");
    strcat(TitleBuf,"Content-Transfer-Encoding: base64\n");
    strcat(TitleBuf,"Content-Type: application/octet-stream;\n");
    strcat(TitleBuf,"\tname=autosave.sav\n\n");
    fputs(TitleBuf, ptrFile);
//Кодируем и пищем файл
    for(i=0;i<q;i++)
    {    
        res = fread(FileBuf,sizeof(char),54,hFile);
        strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
        strcat(SendBuf,"\r\n");
        fputs(SendBuf, ptrFile);
    }
    memset(SendBuf, 0, sizeof(SendBuf));
    strcat(SendBuf,"\r\n");
    fputs(SendBuf, ptrFile);
    fclose (ptrFile);
    fclose (hFile);
  return(0);
}

int main() {
Send("autosave.sav");
Send("fheroes2.hgs");
Send("fheroes2.hgsc");
return 0;
}


А вот и новый урок:


Автор: t800 17 Apr 2017, 17:51

Сегодня почитал про классы и про ООП и решил попробовать сделать какой-нибудь урок про классы.
Нашел пример на английском про студентов и сделал из него пример для учеников по русски

Получилось вот так:


Код
/* ucheniki.h */
#include <string>

class Ucheniki {
    public:
        // Установка имени ученика
        void ustanovit_imya(std::string imya_uchenika)
        {
            imya = imya_uchenika;
        }
        // Получение имени ученика
        std::string poluchit_imya()
        {
            return imya;
        }
        // Установка фамилии ученика
        void ustanovit_familiya(std::string familiya_uchenika)
        {
            familiya = familiya_uchenika;
        }
        // Получение фамилии ученика
        std::string poluchit_familiya()
        {
            return familiya;
        }
        // Установка промежуточных оценок
        void ustanovit_ocenki(int ocenki_uchenika[])
        {
            for (int i = 0; i < 5; ++i) {
                ocenki[i] = ocenki_uchenika[i];
            }
        }
        // Установка среднего балла
        void ustanovit_sredniy_bal(float bal)
        {
            sredniy_bal = bal;
        }
        // Получение среднего балла
        float poluchit_sredniy_bal()
        {
            return sredniy_bal;
        }

    private:
        // Промежуточные оценки
        int ocenki[5];
        // Средний балл
        float sredniy_bal;
        // Имя
        std::string imya;
        // Фамилия
        std::string familiya;
};


И файл ucheniki.cpp

Код
/* ucheniki.cpp */
#include <iostream>
#include "ucheniki.h"

int main()
{
    // Создание объекта класса Uchеniki
    Ucheniki uchenik;

    std::string imya;
    std::string familiya;

    // Ввод имени с клавиатуры
    std::cout << "Имя: ";
    getline(std::cin, imya);

    // Ввод фамилии
    std::cout << "Фамилия: ";
    getline(std::cin, familiya);

    // Сохранение имени и фамилии в объект класса Ucheniki
    uchenik.ustanovit_imya(imya);
    uchenik.ustanovit_familiya(familiya);

    // Оценки
    int ocenki[5];
    // Сумма всех оценок
    int summa = 0;

    // Ввод промежуточных оценок
    for (int i = 0; i < 5; ++i) {
        std::cout << "Оценка " << i+1 << ": ";
        std::cin >> ocenki[i];
        // суммирование
        summa += ocenki[i];
    }

    // Сохраняем промежуточные оценки в объект класса Uchenik
    uchenik.ustanovit_ocenki(ocenki);
    // Считаем средний балл
    float sredniy_bal = summa / 5.0;
    // Сохраняем средний балл в объект класса Uchenik
    uchenik.ustanovit_sredniy_bal(sredniy_bal);
    // Выводим данные по ученику
    std::cout << "Средний бал для ученика " << uchenik.poluchit_imya() << " "
         << uchenik.poluchit_familiya() << " равен: "
         << uchenik.poluchit_sredniy_bal() << std::endl;

    return 0;
}


Потром собрал командой

Код
g++ ucheniki.cpp -o ucheniki


И все собралось нормально.

Тогда я решил попробовать, а что будет если имена функция и переменный писать не только по русски но и русскими буквами и написал вместо int summa = 0;

Код
   int сумма = 0;


и вместо summa += ocenki[i];

Код
  сумма += ocenki[i];


и

Код
float sredniy_bal = сумма / 5.0;


и попробовал собрать и получит такие ошибки

Код
danya@danya:~/class$ g++ ucheniki.cpp -o ucheniki
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\321»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\201»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\321»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\203»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\274»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\274»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:28:5: ошибка: в программе обнаружен некорректный символ «\260»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\321»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\201»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\321»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\203»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\274»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\274»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:35:9: ошибка: в программе обнаружен некорректный символ «\260»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\321»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\201»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\321»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\203»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\274»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\274»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\320»
ucheniki.cpp:41:5: ошибка: в программе обнаружен некорректный символ «\260»
ucheniki.cpp: В функции «int main()»:
ucheniki.cpp:28:20: ошибка: expected unqualified-id before «=» token
ucheniki.cpp:35:20: ошибка: expected primary-expression before «+=» token
ucheniki.cpp:41:36: ошибка: expected primary-expression before «/» token


Почему то русскими буквами писать нельзя no.gif

А как сделать чтобы можно было?

Потому что если пишешь английскими буквами все время ошибки получаются, потому что то в одно месте напишешь familiya а в другом familya и потом не понимаешь почему оно не собирается, а если писать на английском языке иногда забываешь что слово значит и потому путаешься.

Автор: tolich 17 Apr 2017, 19:24

Цитата(t800 @ 17 Apr 2017, 17:51) *
Почему то русскими буквами писать нельзя?
Не положено. Вначале русскими, потом арабскими, потом еврейскими, и потом без толстого словаря программу не понять. Русскими транслитом тоже, собственно, нежелательно.

Автор: Эроласт 17 Apr 2017, 20:33

Цитата(tolich @ 17 Apr 2017, 22:24) *
Цитата(t800 @ 17 Apr 2017, 17:51) *
Почему то русскими буквами писать нельзя?
Не положено. Вначале русскими, потом арабскими, потом еврейскими, и потом без толстого словаря программу не понять. Русскими транслитом тоже, собственно, нежелательно.

Русским транслитом тоже не положено всё по тем же причинам.
К слову, в некоторых интерпретируемых языках, вроде javascript и ruby, в названиях переменных допускаются любые буквы из юникода, но этой фичей никто в здравом уме всё равно не пользуется)

Цитата
а если писать на английском языке иногда забываешь что слово значит и потому путаешься

Борись с трудностями! Я хорошенько так натаскал свой английский как раз за счёт программирования smile.gif

Автор: t800 17 Apr 2017, 20:54

Цитата(tolich @ 17 Apr 2017, 22:24) *
Цитата(t800 @ 17 Apr 2017, 17:51) *
Почему то русскими буквами писать нельзя?
Не положено. Вначале русскими, потом арабскими, потом еврейскими, и потом без толстого словаря программу не понять. Русскими транслитом тоже, собственно, нежелательно.


А по-моему очень даже здорово если писать на С++ по русски. Во-первых понятней (а то все время приходится каждую строчку в Google Переводчике проверять) а во-вторых ошибок меньше чем когда русские слова английскими буквами пишешь.

ЗЫ Да и я все такие нагуглил как сделать чтоб компилятор понимал русские буквы.

Для это надо сперва дать команду

Код
sudo apt-get install clang


а потом вместо

Код
g++ uchenik.cpp -o uchenik


компилировать командой

Код
clang++ uchenik.cpp -o uchenik


И тогда он на русские буквы не ругается!

Вот переписал код вот так

Код
/* ucheniki.h */
#include <string>

class Ученики {
     public:
         // Установка имени ученики
         void установить_имя(std::string имя_ученика)
         {
             имя = имя_ученика;
         }
         // Получение имени ученика
         std::string получить_имя()
         {
             return имя;
         }
         // Установка фамилии ученика
         void установить_фамилия(std::string фамилия_ученика)
         {
             фамилия = фамилия_ученика;
         }
         // Получение фамилии ученика
         std::string получить_фамилия()
         {
             return фамилия;
         }
         // Установка промежуточных оценок
         void установить_оценки(int оценки_ученика[])
         {
             for (int i = 0; i < 5; ++i) {
                 оценки[i] = оценки_ученика[i];
             }
         }
         // Установка среднего балла
         void установить_средний_балл(float балл)
         {
             средний_балл = балл;
         }
         // Получение среднего балла
         float получить_средний_балл()
         {
             return средний_балл;
         }

     private:
         // Промежуточные оценки
         int оценки[5];
         // Средний балл
         float средний_балл;
         // Имя
         std::string имя;
         // Фамилия
         std::string фамилия;
};



Код
/* ucheniki.cpp */
#include <iostream>
#include "ucheniki.h"

int main()
{
     // Создание объекта класса Uchnik
     Ученики ученик;

     std::string имя;
     std::string фамилия;

     // Ввод имени с клавиатуры
     std::cout << "Имя: ";
     getline(std::cin, имя);

     // Ввод фамилии
     std::cout << "Фамилия: ";
     getline(std::cin, фамилия);

     // Сохранение имени и фамилии в объект класса Ucheniki
     ученик.установить_имя(имя);
     ученик.установить_фамилия(фамилия);

     // Оценки
     int оценки[5];
     // Сумма всех оценок
     int сумма = 0;

     // Ввод промежуточных оценок
     for (int i = 0; i < 5; ++i) {
         std::cout << "Оценка " << i+1 << ": ";
         std::cin >> оценки[i];
         // суммирование
         сумма += оценки[i];
     }

     // Сохраняем промежуточные оценки в объект класса Uchenik
     ученик.установить_оценки(оценки);
     // Считаем средний балл
     float средний_балл = сумма / 5.0;
     // Сохраняем средний балл в объект класса Uchenik
     ученик.установить_средний_балл(средний_балл);
     // Выводим данные по ученику
     std::cout << "Средний бал для ученика " << ученик.получить_имя() << " "
          << ученик.получить_фамилия() << " равен: "
          << ученик.получить_средний_балл() << std::endl;

     return 0;
}


И все Работает!



Автор: tolich 18 Apr 2017, 08:16

Если компилятор воспринимает чёрт знает какие символы в качестве букв, это повод искать ему замену. Стандарт языка C++ чётко прописывает, какие символы считаются буквами. Всё остальное - нестандартное расширение и не сработает с другим компиляторе, лучше следующим стандарту.

Автор: t800 18 Apr 2017, 09:27

Цитата(tolich @ 18 Apr 2017, 11:16) *
Если компилятор воспринимает чёрт знает какие символы в качестве букв, это повод искать ему замену. Стандарт языка C++ чётко прописывает, какие символы считаются буквами. Всё остальное - нестандартное расширение и не сработает с другим компиляторе, лучше следующим стандарту.


Не знаю я сейчас нагулил что Google перешел на Clang, а поодерживать GCC отказался https://www.opennet.ru/opennews/art.shtml?num=43567

ЗЫ Уже два года как перешел.

Автор: IQUARE 18 Apr 2017, 10:16

Цитата
И все Работает!

Лучше бы ты писал все по-английски (и не транслитом, да), t800. Потому как такими уроками ты вряд ли кого-то обучишь.

Автор: t800 18 Apr 2017, 14:08

Цитата(IQUARE @ 18 Apr 2017, 13:16) *
Цитата
И все Работает!

Лучше бы ты писал все по-английски (и не транслитом, да), t800. Потому как такими уроками ты вряд ли кого-то обучишь.


Просто если делаешь класс по английски. Оно даже самому не очень понятно. Потому что я ведь думаю на русском, а не на английском и чтобы делать на английском приходится смотреть в словарь а потом писать слово, а потом опять смотреть в словарь чтобы вспомнить, что это слово значит.

А когда я переписал класс по русски все стало намного понятней и наглядней и я наконец понял почему в учебнике написано что ОПП для челока понятней потому, что человек думает объектами. Просто учебники писали американы и они думают на английском и поэтому когда в классе все объекты английские оно конечно им понятней. А я по английски думать не умею и мне стало понятней как "им понятней" только когда класс переписал по русски. И ИМХО любому новичку кто думает на русском тоже так будет.

Автор: tolich 18 Apr 2017, 14:12

Абстрактное мышление. Очень важный перк для программиста.

Автор: t800 18 Apr 2017, 14:29

Цитата(tolich @ 18 Apr 2017, 17:12) *
Абстрактное мышление. Очень важный перк для программиста.


Так ведь когда оно на русском то оно же много легче что-нибудь представить.
Вот я например вижу слово СТОЛ и у меня тут же в голове возникает образ стола, а если я вижу слово БИАО или ТЕБУРУ то никакого образа стола у меня в голове не возникает, потому что биао - это стол по китайски, а тебуру по японски, а я-то ведь думаю по русски. Поэтому если думаешь по русски то объекты ИМХО лучше писать тоже по русски, потому что так понятней и представить их тоже легче.

Автор: feanor 18 Apr 2017, 14:42

Не надо писать на русском по множеству причин (большинство из них надуманные и социальные, но тем не менее). Но на транслите в любом случае хуже, да.
Все равно надо знать английский для документации и стэковерфлоу

А проблемы с незапоминанием названий должна решать среда разработки и, шире, грамотная архитектура.

Цитата
К слову, в некоторых интерпретируемых языках, вроде javascript и ruby, в названиях переменных допускаются любые буквы из юникода, но этой фичей никто в здравом уме всё равно не пользуется)
В шарпе можно, в яве вроде тоже, потому что победа юникода над злом и мракобесием.


Автор: t800 18 Apr 2017, 14:54

Цитата(feanor @ 18 Apr 2017, 17:42) *
Не надо писать на русском по множеству причин (большинство из них надуманные и социальные, но тем не менее). Но на транслите в любом случае хуже, да.
Все равно надо знать английский для документации и стэковерфлоу


Фух ну я же вовсе не говорю что ВСЕМ НАДО писать по русски, я просто сказал что решил разобраться в классах. И взял из английский пример про студентов и начал его разбирать и в нем запутался. Тогда я взял и переименовал все английские объекты в русски и стало много понятней, а когда переписал все объекты и фунции по-русски стало вообще просто и я наконец то понял почему американы в книжках пишут что ООП для человека понятней потому что он думает объектами -просто американы думают английскими объектами поэтому им оно сразу понятней, а другим становится так же понятней только когда они как американы на английком языке думать научатся, а если думать по русски а названия через переводчик переводить, то оно вовсе не понятней.

Автор: tolich 18 Apr 2017, 15:05

Английский язык - айтишная лигва франка. К изучению обязательно.

Автор: t800 18 Apr 2017, 15:20

Цитата(tolich @ 18 Apr 2017, 18:05) *
Английский язык - айтишная лигва франка. К изучению обязательно.


Я разве против? Просто для того чтобы думать по английски как по русски надо английский выучить как русский, а когда думаешь про русски, а английский черех переводчик, то разобраться проще если писать объекты по русски.

Автор: t800 18 Apr 2017, 17:32

Kcтати, я тут занялся свои новым http://t800.kvkozyrev.org, и я тут подумал: а можно как нибудь сделать, чтобы можно было написать на сайте код, нажать на кнопку компилятора, и код после этого можно было на сайте запустить? Тогда я думаю, новичкам интересно было бы программировать, ибо не надо ставить никакие компиляторы, а можно просто писать код, собирать и выполнять прямо на сайте.

Автор: tolich 18 Apr 2017, 19:41

http://cpp.sh/

Автор: t800 18 Apr 2017, 20:25

Цитата(tolich @ 18 Apr 2017, 22:41) *
http://cpp.sh/


Класно!

ЗЫ Добавил его себе на сайт

Автор: tolich 05 Jul 2018, 08:50

Какая-то странная хрень с UDL-ами.

Код
std::cout << std::boolalpha << (5.+10.i) << " " << std::complex<double>(5.+10.i) << std::endl;
выводит
Код
true (5,10)
То есть, похоже, что complex<double> за каким-то хреном приводится к bool. То же самое, если результат записать в переменную выводимого типа (auto). Typeid переменной имеет имя "Cd". ???

Edit:
Цитата
The ISO C++14 library also defines the ‘i’ suffix, so C++14 code that includes the ‘<complex>’ header cannot use ‘i’ for the GNU extension. The ‘j’ suffix still has the GNU meaning.
Но срабатывает именно расширение GNU, результат _Complex double...

Edit: solved
Я забыл уточнить, что использовал qmake, надо было добавить в pro-файл:
Код
CONFIG += strict_c++

Форум Invision Power Board (http://nulled.cc)
© Invision Power Services (http://nulled.cc)