Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Хочу научиться прораммировать на С++  (Прочитано 10982 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Surzh

  • Участник
  • *
  • Сообщений: 153
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #15 : 27 Апреля 2009, 18:02:05 »
Глупый вопрос: как использовать кирилличные символы? Стандартная таблица ASCII работает только до 127 символа.
include <stdio.h>
int main()
{
    unsigned char a;
     a='Я';
     printf("\n%c=%d",a,a);
     return 0;
}
Компилятор ругается на a='Я'; При превышении 127(a=200) компилится, но выдаёт ерунду. В общем в упор не видит русские буквы. Хотя если printf("здраствуй, мир"), то русский печатается нормально. Используется Code::Blocks(консольное приложение) и Ubuntu 9.04. Пакет console-cyrillic ставил, не помогло.
ЗЫ. Интересно, при считывании с текстовых файлов тоже косяки с кодировками будут?

для работы с языками отличными от английского рекомендую использовать wchar_t заместь обычного char
return 0;

Оффлайн lexpartizan

  • Новичок
  • *
  • Сообщений: 44
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #16 : 27 Апреля 2009, 19:36:50 »
Цитировать
для работы с языками отличными от английского рекомендую использовать wchar_t заместь обычного char
Спасибо, попробую. Только мне удобно было как с байтами работать. Хотя может и так выкручусь.

Оффлайн Sova777

  • Участник
  • *
  • Сообщений: 208
    • Просмотр профиля
    • Несколько слов о NetBeans C/C++ Pack'е
Re: Хочу научиться прораммировать на С++
« Ответ #17 : 27 Апреля 2009, 22:55:55 »
У тебя кодировка какая? UNICODE (UTF8). А там русскии буквы - 2 байта. В KOI8R или WINDOWS1251 твоя программа будет работать.
Пользователь OpenSolaris 2008.11, Ubuntu 8.10, Windows XP. Mac OS X не нравится, стараюсь не использовать.

Оффлайн lexpartizan

  • Новичок
  • *
  • Сообщений: 44
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #18 : 28 Апреля 2009, 10:39:17 »
Если не трудно, можете выложить корректный пример программы? А то не выходит каменный цветок. И если возможно пример работы со строкой.

Оффлайн Surzh

  • Участник
  • *
  • Сообщений: 153
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #19 : 28 Апреля 2009, 12:19:23 »
Я вот тут документацию открыл...
1) c - "int" argument is converted to "unsigned char", and then output. Note that this only writes a single character, even if the original "int" value held more than one character.
2) d - "int" argument is output as a signed decimal integer. If the number is positive, a '+' sign may or may not be output, depending on the value of the modifiers field.

В обоих случаях он на вход хочет получить int. А ты ему чары даешь :)

Для более подробной информации о флагах читай: http://www.thinkage.ca/english/gcos/expl/nsc/lib/printf.html

З.Ы.: Для мультибайтных строк и символов используется команда wprintf
return 0;

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #20 : 03 Мая 2009, 10:09:00 »
lexpartizan, на самом деле в твоём исходнике буковка 'Я' представлена несколькими байтами (я почти уверен что исходник набран в кодировке UTF-8, которая ставится по умолчанию в Ubunt'е), чего по синтаксису языка нельзя делать. тем более несколько байтиков в выделенный тобою один unsigned char ну никак не влезут. зато в wchar_t влезет любой символ из любого языка. 2009 год на дворе. пора писать unicode-ные приложения.
Вот исходник
Код: ("test.c") [Выделить]
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#include <wchar.h>

int main()
{
        wchar_t wc = L'Я';
        setlocale(LC_ALL, getenv("LANG"));
        wprintf(L"%lc есть %s\n", wc, getenv("USER"));
        return EXIT_SUCCESS;
}

Для компиляции
gcc -std=c99 -Wall -Wextra test.c -o test

hint: man wprintf и англо-русский словарик

2 Sova777: UTF-8 есть кодировка с переменной длиной символа! Так что твои 2 байта это пальцем в небо... повезло что угадал. =)
в кодировках KOI8R или win1251 оно конечно соберется... но вот работать будет через пень колоду... и в самой программе надо будет самому следить за кодировками. если на это забить, то пользователи в итоге будет иметь что-то типа фуфла Photoshope которому надо прописывать в реестре ключики что-бы кодировки нормально отображались у "локализованной" версии.
таки средства locale.h использовать предпочтительнее.

Оффлайн yaromir

  • Активист
  • *
  • Сообщений: 670
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #21 : 03 Мая 2009, 23:33:49 »
Yurror, и от меня спасибо за ликбез.
Цитировать
UTF-8 есть кодировка с переменной длиной символа!
Разве байт не является неделимой единицей?

Оффлайн Surzh

  • Участник
  • *
  • Сообщений: 153
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #22 : 04 Мая 2009, 00:02:13 »
Yurror, и от меня спасибо за ликбез.
Цитировать
UTF-8 есть кодировка с переменной длиной символа!
Разве байт не является неделимой единицей?


символ != байт (в понятии Unicode)
return 0;

Оффлайн yaromir

  • Активист
  • *
  • Сообщений: 670
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #23 : 04 Мая 2009, 00:15:01 »
Т.е. может быть символ, например, длиной 3 бита? Круто. А как выглядит переменная wchar_t, которая его хранит?

Оффлайн Surzh

  • Участник
  • *
  • Сообщений: 153
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #24 : 04 Мая 2009, 00:17:27 »
Т.е. может быть символ, например, длиной 3 бита? Круто. А как выглядит переменная wchar_t, которая его хранит?

3 бита - нет.. а вот 2 байта или 3 байта - запросто...

Подробнее тут: http://ru.wikipedia.org/wiki/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4
return 0;

Оффлайн yaromir

  • Активист
  • *
  • Сообщений: 670
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #25 : 04 Мая 2009, 00:23:07 »
Написал маленькую программку на Си:
#include <stdio.h>
#include <wchar.h>

int main(void)
{
    printf( "Size of wchar_t %i\n"
            "Size of char    %i\n",
            sizeof(wchar_t), sizeof(char)
          );
    return 0;
}
и запутался окончательно.
wchar_t - 4 байта,
char - 1 байт.
Что тогда означает цифра 8 в UTF-8 ?
« Последнее редактирование: 04 Мая 2009, 00:34:21 от Oldwise »

Оффлайн unimix

  • Активист
  • *
  • Сообщений: 537
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #26 : 04 Мая 2009, 00:49:08 »
3 бита - нет.. а вот 2 байта или 3 байта - запросто...

Если не использовать UTF, а самому реализовать динамический способ кодирования символов, то некоторый символ может быть 3 бита (и даже 2 бита, но эти варианты -- не лучшее решение). Конечно, храниться такие символы могут только в байтах: один символ в 3 бита фактически займет 1 байт; два символа в 3 бита тоже займут 1 байт. К примеру, если есть необходимость, то таким способом можно хранить и double, где в зависимости от числа зависит количество используемых байтов. С и С++ позволяют такое сделать.

П.С.
Это так, информация к размышлению кому интересно.



Что тогда означает цифра 8 в UTF-8 ?

http://ru.wikipedia.org/wiki/UTF-8
« Последнее редактирование: 04 Мая 2009, 00:53:35 от unimix »

Оффлайн yaromir

  • Активист
  • *
  • Сообщений: 670
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #27 : 04 Мая 2009, 01:00:19 »
У числовой переменной должно быть 4 сегмента:
знак - знак  :)  ;
радикс - система исчисления: двоичная, восьмеричная, десятичная, шестнадцатиричная ;
мантисса - мантисса числа  :)  ;
экспонента - степень, в которую нужно возвести десять.
Например 12 в десятичной системе исчисления кодируется так:
+ 10 1.2 1
Т.е. + 1.2 * 10^1;
Поэтому в С и С++ инт - 4 байта, флоат - 4 байта, дабл - 8 байт - каждому сегменту по 2 байта (или мантиссе и экспоненте по 3 байта, тут яхз. Хотя не, наверно все же по 2 байта каждому сегменту: дабл - двойной.)
В общем, см. загловок cfloat и http://www.cplusplus.com/

Цитировать
К примеру, если есть необходимость, то таким способом можно хранить и double, где в зависимости от числа зависит количество используемых байтов. С и С++ позволяют такое сделать.
Получается, в дабле сэкономить можно только на мантиссе и экспоненте, зачем тогда так извращаться с даблом, не проще использовать флоат? Если только из научных интересов.

Оффлайн Surzh

  • Участник
  • *
  • Сообщений: 153
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #28 : 04 Мая 2009, 01:01:42 »
3 бита - нет.. а вот 2 байта или 3 байта - запросто...

Если не использовать UTF, а самому реализовать динамический способ кодирования символов, то некоторый символ может быть 3 бита (и даже 2 бита, но эти варианты -- не лучшее решение). Конечно, храниться такие символы могут только в байтах: один символ в 3 бита фактически займет 1 байт; два символа в 3 бита тоже займут 1 байт. К примеру, если есть необходимость, то таким способом можно хранить и double, где в зависимости от числа зависит количество используемых байтов. С и С++ позволяют такое сделать.

П.С.
Это так, информация к размышлению кому интересно.


Хаффман - наше все :)

(Нажмите, чтобы показать/скрыть)
return 0;

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Хочу научиться прораммировать на С++
« Ответ #29 : 04 Мая 2009, 05:47:43 »
Oldwise, в C и C++ не определены размеры встроенных типов данных. Определено лишь отношение этих размеров. char<=short<=int<=long<=long long
Собственно размер зависит от платформы и модели данных используемой на этой платформе
// Data models
// Data Type            LP32    ILP32    SILP64    ILP64    LLP64    LP64
// char                    8        8         8        8        8       8
// short                  16       16        64       16       16      16
// int                    16       32        64       64       32      32
// long                   32       32        64       64       32      64
// long long (int64)      64       64        64       64       64      64
// pointer                32       32        64       64       64      64

// __int8                 8         8         8        8        8       8
// __int16                16       16        16       16       16      16
// __int32                32       32        32       32       32      32
// __int64                64       64        64       64       64      64
/*
MacOS (Apple Mac) 32 - LP32
LLP64  - for 32 bit application on 64 bit os
OS   Mode 
Windows XP-64 / IA64   LLP64 
Linux   LP64 
Solaris   LP64 
DEC OSF/1 Alpha   LP64 
SGI Irix   LP64 
HP UX 11   LP64
*/

 

Страница сгенерирована за 0.019 секунд. Запросов: 21.