Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > регистр букв


Автор: Ramigo 20.1.2007, 13:47
Встал вопрос вот в чем:что за оператор для замены ргистра буквы в С++?короче надо написать прогу чтоб та меняла регистр т.е. с большой на маленькую и наоборот..перерыл все учебники но не нашел(((помогите плиззз!

Автор: szz 20.1.2007, 13:51
Код

#include <string>
string myString("HeLlO, WoRlD!");
strupr((char *) myString.c_str());


Добавлено @ 13:52 
http://www.gnu.org/software/libc/manual/html_node/Case-Conversion.html

Автор: Ramigo 20.1.2007, 13:58
бошое пасибо!но в силу еще своей неопытности:эт вводится до функции main?первая строка само собой....

Автор: bsa 20.1.2007, 14:17
Цитата(Ramigo @ 20.1.2007,  13:58)
бошое пасибо!но в силу еще своей неопытности:эт вводится до функции main?первая строка само собой....

Внутри main

Автор: Rockie 20.1.2007, 14:28
Ramigo, toupper, tolower
Код

// 
// toupper.cpp
//
#include <iostream>
int main ()
{
  using namespace std;
  locale loc;
  cout << 'a' << toupper('c') << tolower('F') << endl;
 
  return 0;
}

а вообще для английских букв даже этого не нужно. Английский алфавит в кодировке ASCII располагается последовательно, сначала большие буквы, потом 6 символов, потом маленькие. Поэтому 
 'A'+32 == 'a' и соответсвенно наоборот


Автор: bsa 20.1.2007, 15:06
Цитата(Rockie @ 20.1.2007,  14:28)
а вообще для английских букв даже этого не нужно. Английский алфавит в кодировке ASCII располагается последовательно, сначала большие буквы, потом 6 символов, потом маленькие. Поэтому 
 'A'+32 == 'a' и соответсвенно наоборот

Смысл правильный, а вывод нет.
Из маленьких ASCII большие: a = c & 0xDF или a = c & (0xFF ^ 0x20)
Из больших ASCII маленькие: a = c | 0x20
здесь c - любой буквенный символ (регистр значения не имеет)

Кажется, будет работать и с кодировками CP1251/KOI8-R для русских букв, но я не проверял.

Автор: Rockie 20.1.2007, 15:36
Цитата(bsa @  20.1.2007,  15:06 Найти цитируемый пост)
Смысл правильный, а вывод нет.

почему?

Код
#include<iostream>

int main()
{

  for(char letter='A';letter<'[';letter++)
   {
      std::cout<<letter<<' '<<char(letter+32)<<std::endl;
   }

  std::cin.get();
  return 0;
}


Цитата(bsa @  20.1.2007,  15:06 Найти цитируемый пост)
Из маленьких ASCII большие: a = c & 0xDF[b] или [b]a = c & (0xFF ^ 0x20)Из больших ASCII маленькие: a = c | 0x20

непонятно, но интересно smile А что здесь происходит?


Автор: Axxent 20.1.2007, 16:04
Разница невелика, просто процу быстрее проставить шестой бит в единицу или ноль чем прибавить или отнять 32. Результат одинаков. Что происходит - происходит побитовая установка по маске. a = b & 0xDF - побитовое И с маской 11011111, a = b | 0x20 - побитовое ИЛИ с маской 00100000.

Автор: bsa 20.1.2007, 16:23
Цитата(Axxent @ 20.1.2007,  16:04)
Разница невелика, просто процу быстрее проставить шестой бит в единицу или ноль чем прибавить или отнять 32.

Для меня это открытие. Не знал, что скорость выполнения этих операций разная...
Вариант со сложением я посчитал не очень корректным, так как он неправильно обработает буквы в другом регистре. Т.е. операция с И и ИЛИ более корректно отработают "This simple string", а вот операции сложения/вычитания накосячат.

Автор: Axxent 20.1.2007, 16:35
Тоже верно. Разница есть, если строк мало то при прочих равных ей можно пренебречь, но все же побитовые операции выполняются чуть-чуть быстрее.

Автор: nickless 20.1.2007, 16:47
Цитата(Axxent @ 20.1.2007,  15:35)
побитовые операции выполняются чуть-чуть быстрее.

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

Автор: bsa 20.1.2007, 16:51
Цитата(Axxent @ 20.1.2007,  16:35)
Тоже верно. Разница есть, если строк мало то при прочих равных ей можно пренебречь, но все же побитовые операции выполняются чуть-чуть быстрее.

Интересно, это как быстрее?!? Скорость сложения (на процессорах Pentium и выше) 1 такт. Скорость операции OR по твоему 0.99 такта?  smile 
Цитата(http://www.ixbt.com/cpu/cpu-microarchitecture-part-2.shtml)
Латентность большинства операций целочисленной арифметики составляет 1 такт, а их суммарный темп исполнения — 2 операции за такт, по одной в устройствах, подсоединённых к портам 0 и 1. Некоторые операции (сложения/вычитания и копирования, а также логические) могут выполняться в устройствах на обоих портах. Также в каждом такте может быть произведено одно считывание из L1-кэша и одна запись в L1-кэш (64-разрядные).
Лень было искать первоисточники, взял первое попавшееся.

Автор: Axxent 20.1.2007, 17:06
Мда, прокосил smile Прошу у всех прощения. Попутал с умножением и сдвигами smile Впрочем как уже было сказано на современных оно тоже не слишком разнится

Автор: Rockie 20.1.2007, 17:09
Цитата(Axxent @  20.1.2007,  16:04 Найти цитируемый пост)
 a = b & 0xDF - побитовое И с маской 11011111, a = b | 0x20 - побитовое ИЛИ с маской 00100000.

bsa, Axxent, а побитовое И чего с чем? что такое a и b?  

Цитата(bsa @  20.1.2007,  16:23 Найти цитируемый пост)
 Т.е. операция с И и ИЛИ более корректно отработают "This simple string", а вот операции сложения/вычитания накосячат.

bsa, в этой строке пробелы, они ведь не переводятся в верхний/нижний регистр. А можно пример кодом где вариант с масками не косячит а сложение/вычитание косячит?

Цитата(Axxent @  20.1.2007,  16:04 Найти цитируемый пост)
Разница невелика, просто процу быстрее проставить шестой бит в единицу или ноль чем прибавить или отнять 32.

imho современный компилятор должен это соптимизировать.

Добавлено @ 17:20 
вообще кажися просветлеваю =)

bsa, имеется ввиду, что при варианте с установкой бита буква 'S' останется 'S'? 


Автор: Axxent 20.1.2007, 17:22
a - куда результат помещаем, b - твое число или символ. В двоичном коде допустим А = 0x41 = 01000001b, хочешь сделать маленькой - поставь шестой бит: A | 0x20 = 01000001 | 00100000 = 01100001 = a.
Цитата
The simple string

Мелкие буквы. Большая первая станет маленькой, к остальным еще +32. Получится галиматья.

Автор: Rockie 20.1.2007, 17:31
Axxent, ага, спасибо, уже дошел =) просто
Цитата(bsa @  20.1.2007,  15:06 Найти цитируемый пост)
a = c & 0xDF[b] или [b]a = c & (0xFF ^ 0x20)

для меня не совсем user-friendly. 


Автор: bsa 20.1.2007, 17:39
Забыл слэш поставить. Уже исправил.
Там нет никакого b - это от phpBB (жирный шрифт).  smile 

читать надо так: a = c & 0xDF или a = c & (0xFF ^ 0x20), что тоже самое
Просто 0xFF ^ 0x20 = 0xDF (это для тех, кто не умеет оперировать 16-тиричными числами)

Автор: Rockie 20.1.2007, 17:45
Кстати интересно, что способ этот работает только по причине того что буквы лежат в том интервале, в котором лежат. Похоже именно ради того, чтобы освободить этот бит буквы располагаются так:

65[10] = 1000001[2] ..   90[10] = 1011010[2]
97[10]=  1100001[2] .. 122[10] = 1111010[2]

и между интервалами добавлены "лишние" символы, чтобы "добить" до 32.

Цитата(bsa @  20.1.2007,  17:39 Найти цитируемый пост)
Там нет никакого b - это от phpBB

бугага smile


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)