C/C++

Не работает std::toupper()

В отдельном файле сделал класс с ресурсами для заполнения бд. Сделал class Map : public map<string,string> и в конструкторе из файла забиваю в словарь данные. Мне для простоты проверок удобнее, чтобы все буквы были заглавные, но поднять символ никак не могу. Поднять строку перед передачей в key или value тоже не выходит. Когда тещу в мейне, то всё работает отлично. Почему?
Roma_ Akimov&
Roma_ Akimov&
36
С кодировками все хорошо? По умолчанию toupper работает с однобайтной кодировкой и с латинскими буквами. Для поддержки кириллицы требуется устанавливать соответствующую локаль: setlocale(...). Если файл записан в UTF-8 кодировке, то только латиница правильно будет обрабатываться. А индексация сломается на первом же двубайтном символе.
Напишите отладочную версию функции, которая будет отображать какой символ считался в переменную s, и каким он стал после обработки toupper.
Виктор Спицин
Виктор Спицин
51 416
Лучший ответ
Андрей Хаджи Тут, походу, не только с кодировками все плохо.
Ты Солнце тоже вручную закатываешь, по миллиметру? Нужно конвертировать - используй функции БД, а не плюсов. Вплоть до использования триггеров, если нужно. Не придется думать о кодировках и всей прочей чуши.
Камрад, хотел бы обратить ваше внимание на последний оператор if
Метод empty() возвращает true когда строка пуста.
Вот логический эквивалент оператора if из конца вашей чудесной программы:
 #include  

int main( int argc, char* argv[] )
{
bool key_empty = false;
bool val_empty = false;

std::cout
Андрей Шумилов А вот так правильно:
 if( key.length() && val.length() )
{
// добавляем данные в std::map, не забыая контролировать
// повторное добавление и успешность выделения памяти
}
Андрей Шумилов Что касается именно перевода букв из одного регистра в другой, то в стандартных средствах Си/Си++ тут все, мягко говоря, не очень весело. Я бы всерьез подумал над тем, чтобы сделать конверсию на другом языке либо пользоваться средствами БД, как посоветовали выше.
Андрей Шумилов Преобразовани считанных из STDIN строк в UTF-8 к верхнему регистру:
Python:
 #!/usr/bin/python3 
import sys
for line in sys.stdin:
print(line.rstrip('\n').upper())
Rust:
 use std::io; 
use std::io::BufRead;
use std::io::BufReader;
fn main()
{
let br = BufReader::new(io::stdin());
for (n,r) in br.lines().enumerate()
{
match r
{
Ok(line) => { println!("{}", line.to_uppercase()); },
Err(err) => { eprintln!("Строка {}: {}", n, err); },
}
}
}
Go:
 package main
import "os"
import "fmt"
import "bufio"
import "strings"
func main(){
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
line := strings.ToUpper( scanner.Text() )
fmt.Println(line)
}
}
Roma_ Akimov& Так мне и надо чтоб заполнение шло когда и key и value не пусты
Судя по описанию, проблема может быть связана с тем, что вы пытаетесь применить функцию std::toupper() к объекту типа string, который является неизменяемой (immutable) строкой.

Функция std::toupper() изменяет регистр символов в строке, на которую указывает переданный ей указатель. Однако объекты типа string не позволяют изменять свое содержимое непосредственно, так как они являются неизменяемыми.

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


 #include  
#include
#include

// Функция преобразования строки в верхний регистр
void toUpperString(std::string& str) {
std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::toupper(c); });
}

// Пример использования
int main() {
std::string s = "Hello, World!";
toUpperString(s);
// s теперь содержит "HELLO, WORLD!"
return 0;
}
Вы можете применить эту функцию к каждой строке перед ее добавлением в map.
Бро надо просто выкинуть комп с окна