Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
2 / 2 / 2
Регистрация: 02.07.2012
Сообщений: 38
1

Кириллица в структуре весит в 2 раза больше

08.04.2014, 08:25. Показов 2640. Ответов 10
Метки нет (Все метки)

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
struct namect{
    char *fname;
    char *lname;
    int letters;
};
 
void getinfo(struct namect*);
void makeinfo(struct namect*);
void showinfo(const struct namect*);
void cleanup(struct namect*);
 
int main(void)
{
    struct namect person;
    getinfo(&person);
    makeinfo(&person);
    showinfo(&person);
    cleanup(&person);
    return 0;
}
 
void getinfo(struct namect *pst)
{
    char temp[81];
    printf("Введите свое имя.\n");
    gets(temp);
    pst->fname = (char*)malloc(strlen(temp) + 1);
    strcpy(pst->fname, temp);
    printf("Введите свою фамилию.\n");
    gets(temp);
    pst->lname = (char *)malloc(strlen(temp) + 1);
    strcpy(pst->lname, temp);
}
 
void makeinfo(struct namect *pst)
{
    pst->letters = (strlen(pst->fname) + strlen(pst->lname));
}
 
void showinfo(const struct namect *pst)
{
    printf("%s %s, ваше имя и фамилия содержат %d букв.\n", pst->fname, pst->lname, pst->letters);
}
 
void cleanup(struct namect *pst)
{
    free(pst->fname);
    free(pst->lname);
}
Почему так происходит?

Пример output:
Введите свое имя.
Артем
Введите свою фамилию.
Александров
Артем Александров, ваше имя и фамилия содержат 32 букв.
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.04.2014, 08:25
Ответы с готовыми решениями:

Больше фруктов. Определить, что весит больше - яблоки или апельсины
Больше фруктов. Одно яблоко весит 100 гр., а один апельсин 150 гр.Вам дают заданное кол-во яблок...

Существует ли треугольник АВС, у которого АВ = 7 см, ВС в два раза больше АВ, а АС в три раза больше АВ
15. Существует ли треугольник АВС, у которого АВ = 7 см, ВС в два раза больше АВ, а АС в три раза...

Что больше весит? :))
Доброго времени суток, уважаемы программисты! У меня нестандартненький вопросик :) Что больше...

Почему ссылка весит больше переменной
Почему ссылка весит больше переменной &lt;?php $a=memory_get_usage(); $bar = &amp;$foo;...

10
Модератор
Эксперт по электронике
8490 / 6317 / 854
Регистрация: 14.02.2011
Сообщений: 21,888
08.04.2014, 08:32 2
Цитата Сообщение от obrazz Посмотреть сообщение
ваше имя и фамилия содержат 32 букв.
скорее всего юникоде набор используется
поиграйся с настройками консоли
0
2 / 2 / 2
Регистрация: 02.07.2012
Сообщений: 38
08.04.2014, 10:04  [ТС] 3
Да стоит в настройках UTF8. И всегда стояло и никогда не было проблем с типом char неважно какие символы используются латиница или кириллица и сейчас нету. Проблема возникает при создании массивов типа char или указателей на тип char конкретно внутри структуры. В функции main() или в глобальной области видимости все в порядке. Если использую латинские символы тоже все в порядке и в структурах в том числе.
З.Ы. куда копать ума не приложу. Сижу на Ubuntu 12.04 x64, gcc 4.7

Добавлено через 17 минут
Извиняюсь, затестил только что, проблема имеет место быть везде. Я полагаю было какое-то обновление.
0
Модератор
Эксперт по электронике
8490 / 6317 / 854
Регистрация: 14.02.2011
Сообщений: 21,888
08.04.2014, 10:23 4
Цитата Сообщение от obrazz Посмотреть сообщение
И всегда стояло и никогда не было проблем с типом char неважно какие символы используются латиница или кириллица и сейчас нету. Проблема возникает при создании массивов типа char или указателей на тип char конкретно внутри структуры. В функции main() или в глобальной области видимости все в порядке.
по моему дело не в программе
массив чар он нормально отрабатывает, проблемы при вводе, вместо одного бита приходит 2

посмотри что в буфере вот таким примерно кодом

C++
1
2
3
4
5
6
void PrintfBuf(char * buf)
{
for(int i=0; buf[i];i++)
  printf("%c %xh  ",buf[i],buf[i];
 
}
вызвать соответственно так
C++
1
PrintfBuf(pst->fname);
1
Эксперт Java
3851 / 2471 / 445
Регистрация: 28.04.2012
Сообщений: 8,132
08.04.2014, 11:00 5
Цитата Сообщение от obrazz Посмотреть сообщение
Да стоит в настройках UTF8. И всегда стояло и никогда не было проблем с типом char неважно какие символы используются латиница или кириллица и сейчас нету. Проблема возникает при создании массивов типа char или указателей на тип char конкретно внутри структуры.
Рекомендую таки ознакомиться с форматом.
Кирилические символы в UTF-8 занимают два байта, т.е. два char'а.
1
Эксперт Java
3851 / 2471 / 445
Регистрация: 28.04.2012
Сообщений: 8,132
08.04.2014, 11:19 6
Например:
1
Миниатюры
Кириллица в структуре весит в 2 раза больше  
Эксперт Java
3851 / 2471 / 445
Регистрация: 28.04.2012
Сообщений: 8,132
08.04.2014, 11:25 7
Даже точнее так:
1
Миниатюры
Кириллица в структуре весит в 2 раза больше  
2 / 2 / 2
Регистрация: 02.07.2012
Сообщений: 38
08.04.2014, 19:25  [ТС] 8
Я что-то совсем запутался.
Раньше все было норм, в debian stable x64 на gnome3.4, yakuake.
Потом все было норм и в Ubuntu 12.04 x64 yakuake.
Но вот вчера начались косяки. Строки с символами кириллицы стали занимать больше места.
По ответам я так и не понял то ли это нормально, то ли нет и нужно исправлять. Дайте пожалуйста подробный ответ.
Знания английского у меня пока скудные и терпения хватает только на учебник.
З.Ы. Если нужно что-то настраивать дайте алгоритм действий. Знания ubuntu у меня не высоки. Ползал по настройкам yakuake и простого терминала корректно кириллица отображается только в UNICODE > UTF-8.
0
Эксперт Java
3851 / 2471 / 445
Регистрация: 28.04.2012
Сообщений: 8,132
08.04.2014, 21:01 9
Цитата Сообщение от obrazz Посмотреть сообщение
Знания английского у меня пока скудные и терпения хватает только на учебник.
На википедии внезапно есть и на русском статьи.

Цитата Сообщение от obrazz Посмотреть сообщение
По ответам я так и не понял то ли это нормально, то ли нет и нужно исправлять.
Кирилица в UTF-8 занимает два байта. Я же показал пример. Возможно у тебя до этого стояла другая, однобайтовая кодировка.

Поэтому да, нужно исправлять. Самый простой способ, который я знаю — воспользоваться библиотеками из Plan9Port, они умеют работать с UTF-8, я показал пример, только там, вместо моей «наколеночной» utf8len, лучше воспользоваться библиотечной utflen:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <u.h>
#include <libc.h>
 
void
main(int argc, char *argv[])
{
    int i;
    long chars, runes;
 
    chars = runes = 0;
    for (i = 1; i < argc; i++) {
        chars += strlen(argv[i]); // количество байт
        runes += utflen(argv[i]); // количество «символов»
    }
    print("байт:       %20ld\n", chars);
    print("«символов»: %20ld\n", runes);
 
    exits(0);
}
Bash
1
2
3
4
5
6
7
~/prog/c $ ./utflen Артем Александров
байт:                         32
«символов»:                   16
~/prog/c $ ./utflen Привет World
байт:                         17
«символов»:                   11
~/prog/c $
1
2 / 2 / 2
Регистрация: 02.07.2012
Сообщений: 38
09.04.2014, 06:41  [ТС] 10
Спасибо за ответы.
Нашел в библиотеке Си наборы функций для работы с широкими символами:
http://www.cplusplus.com/reference/cwchar/
http://www.cplusplus.com/reference/cwctype/
http://www.cplusplus.com/reference/clocale/
Попробую выработать привычку использования этих функций.

Добавлено через 26 минут
Может кому-нибудь поможет нашел в интернете пример использования функций для широких символов.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h> //Стандартный однобайтовый ввод-вывод
#include <wchar.h> //"Широкие" многобайтовые символы и их ввод-вывод
#include <wctype.h> //"Классификация" широких символов
#include <locale.h> //Во избежание "крокозяблей" на выводе
 
#define MAXSTR 100
 
int main()
{
 
 int i = 0;
 wchar_t wmsg[MAXSTR] = L"Добро Пожаловать!";
 // Широкие строчные константы требуют L
 
 if (! setlocale(LC_ALL, "ru_RU.utf8"))
 //Используем Линукс с Unicode UTF8 консолью
  return 1;
 
 wprintf(L"%ls\n", wmsg);
 //Широкие функции требуют L даже в спецификаторе формата.
 //С этого момента мы НЕ МОЖЕМ пользоваться printf (и другими однобайтовыми
 //функциями ввода-вывода) на потоке stdout.
 
 if (! wscanf(L"%ls", wmsg) ) //Небезопасный ввод
  return 2;
 else
 {
  wprintf(L"Вы ввели: %ls\n", wmsg);
  //Правильный анализ широких строк возможен ТОЛЬКО с использованием
  //многобайтных функций.
  //Смотрите ISO/IEC 9899:1999.
  if ( iswupper( (wint_t) wmsg[0]) )
   wprintf(L"Первая буква Большая!\n");
   //Однобайтовый конец строки автоматически переводится в Unicode.
 
  wprintf(L"ЗАГЛАВНЫМИ:\t");
  while (wmsg[i] != '\0')
   putwchar (towupper (wmsg[i++]) );
  putwchar('\n');
 
 }
 
 return 0;
}
0
918 / 635 / 198
Регистрация: 08.09.2013
Сообщений: 1,690
09.04.2014, 10:22 11
Цитата Сообщение от obrazz Посмотреть сообщение
wprintf(L"Первая буква Большая!\n");
//Однобайтовый конец строки автоматически переводится в Unicode.
В данной строке ВСЕ символы широкие.
При выводе на stdout широкие символы функцией wprintf переводятся в utf-8. Русские буквы - в два байта, пробелы и конец строки - в один байт.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.04.2014, 10:22

Почему, если я объявляю массив, он весит больше?
задаю массив char*array = new char; а в оперативе массив занимает 4 килобайта. почему так...

Какая часть пачек сахара весит больше 1.03 кг
Вес упаковки сахара нормально распределен со средним значением 1 кг. Известно, что 20% из всех...

Кирпич весит килограмм плюс полкирпича. Вопрос: сколько весит кирпич?
Задачка на сообразительность для выявления типа мышления: кирпич весит килограмм плюс полкирпича....

Подсчитать количество вхождений буквы (кириллица) в строку (кириллица)
Суть такая: по требованию программы ввести строку символов (обыкновенный текст, кириллица(!!!)) и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.