2016-09-27 4 views
1

Мне нужно распечатать некоторые данные в консоли. Мой код:C++ setw() не работает как ожидалось

cout << setw(5) << left << "id" << " | " << setw(10) << left << "computer" << " | " << setw(11) << left << "subsystem" << " | " << 
     setw(8) << left << "number" << " | " << setw(80) << left << "name" << " | " << setw(13) << left << "config_file" << endl; 
    for (int i = 0; i < rows; i++) 
     { 
     cout << setw(5) << left << subsystem_table_data[i].id << " | " << setw(10) << left << subsystem_table_data[i].computer << " | " << 
       setw(11) << left << subsystem_table_data[i].subsystem << " | " << setw(8) << left << subsystem_table_data[i].number << " | " << 
       setw(80) << left << subsystem_table_data[i].name << " | " << setw(13) << left << subsystem_table_data[i].config_file << endl; 
     } 

Output (прокрутка вправо, чтобы увидеть):

id | computer | subsystem | number | name                    | config_file 
1  | 1   | 2   | 0  | Computer 1 - Общая компьютерная платформа - 1   | 1    
2  | 1   | 1   | 0  | Computer 1 - Launcher - 1              | 2    
3  | 1   | 23   | 0  | Computer 1 - Дисплей - 1             | 3    
4  | 1   | 11   | 0  | Computer 1 - Контроллер цифровой - 1       | 4    
5  | 1   | 21   | 0  | Computer 1 - Отладки - 1             | 5    
6  | 2   | 2   | 0  | Computer 2 - Общая компьютерная платформа - 1   | 6    
7  | 2   | 1   | 0  | Computer 2 - Launcher - 1              | 7    
8  | 2   | 23   | 0  | Computer 2 - Дисплей - 1             | 8   

Ожидаемый результат (справа снова):

id | computer | subsystem | number | name                    | config_file 
1  | 1   | 2   | 0  | Computer 1 - Общая компьютерная платформа - 1         | 1    
2  | 1   | 1   | 0  | Computer 1 - Launcher - 1              | 2    
3  | 1   | 23   | 0  | Computer 1 - Дисплей - 1               | 3    
4  | 1   | 11   | 0  | Computer 1 - Контроллер цифровой - 1            | 4    
5  | 1   | 21   | 0  | Computer 1 - Отладки - 1               | 5    
6  | 2   | 2   | 0  | Computer 2 - Общая компьютерная платформа - 1         | 6    
7  | 2   | 1   | 0  | Computer 2 - Launcher - 1              | 7    
8  | 2   | 23   | 0  | Computer 2 - Дисплей - 1               | 8    

я предлагаю что-то неладно с setw(80) << left << subsystem_table_data[i].name код, но не может найти проблему. И, насколько я знаю, это происходит не из-за общей ширины консоли, так как первая строка напечатана просто отлично.

ответ

4

setw() работает как запроектирован. Он выдает выходной сигнал на заданное число байтов .

Проблема в том, что вам не нужно количество байтов, вам нужна ширина текста, но если ваш текст не является чисто ASCII и не печатается моноширинным шрифтом, эти две вещи разные.

Различия возникают на нескольких уровнях:

  1. Unicode кодовые точки выше диапазона ASCII кодируются (предполагая, что в UTF-8, это выглядит, как выход в UTF-8 из числа байтов, различных линии берутся) в виде нескольких байтов.
  2. Несколько кодовых точек могут объединяться в один символ. Если вы используете составленную нормальную форму, которая является стандартом, за исключением файловой системы MacOS, все кириллические глифы представляют собой единую кодовую точку, но в разложенной форме «й» будет двумя.
  3. Символы могут иметь разную ширину экрана.

Первым моментом является то, что вызывает несоосность, возможно, в сочетании со вторым, если на вашем входе могут появиться разложенные символы. Пока вы выходите с использованием моноширинного шрифта, третий не является проблемой для кириллицы, но если есть вероятность, что вы можете столкнуться с каким-то китайским/японским/корейским текстом, имейте в виду, что их глифы в основном «полные» и те берут пробел двух латинских или кириллических букв на большинстве терминалов.

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


Документация operator<<(std::ostream&, std::string const&) описывает эффект width() в срок std::string::size() и это определенно байт.

Смежные вопросы