C++ setw()不按预期方式工作

C++ setw()不按预期方式工作

问题描述:

我需要在控制台上打印一些数据。我的代码是: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; 
     } 

输出(向右滚动才能看到):

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代码部分,但似乎无法找到问题。据我所知,这不是因为控制台总宽度,因为第一行打印得很好。

setw()按设计工作。它将输出填充到给定数量的字节

问题是你不需要字节数,你需要文本宽度,但除非你的文本是纯粹的ASCII和打印等宽字体,这两件事情是不同的。

的差异发生在几个级别:

  1. Unicode代码点以上ASCII范围进行编码(假定UTF-8;它看起来像输出为UTF-8从不同的字节数行正在)作为多个字节。
  2. 多个代码点可以组合成单个字形。如果您使用的是除MacOS文件系统外的标准格式,所有西里尔字形都是单一的代码点,但是以分解形式,“й”将是两个。
  3. 字形可能需要不同的屏幕宽度。

第一点是什么导致您的错位,如果分解的字符可能出现在您的输入中,可能与第二点相结合。只要你使用等宽字体输出,第三个不是西里尔文的问题,但是如果你有可能遇到一些中文/日文/韩文文本,请记住它们的字形大多是“全角”,而那些在大多数终端上占用两个拉丁字母或西里尔字母的空间。

C++标准库不支持计算字形。你需要使用一个unicode支持库(如ICU),并自己处理对齐—,或者采取简单的方法,使文本列成为最后一个,所以它的结束并不重要。


operator<<(std::ostream&, std::string const&)该文档描述的width()效果的std::string::size()术语,这是绝对字节。