C ++字符串格式 - 固定宽度浮点,以及偏移空格的字符串

时间:2014-06-08 19:08:58

标签: c++

我正在玩stringstreams,我有一句话:

10 651.23 Some longer name

我想把它变成uint,double和string,如10,651.23,“一些更长的名字”

所以我试过

    iss >> quantity >> price >> std::noskipws >> name;

但它看起来并不那么容易。我怎样才能得到包括空格的其余字符串?

后来我想显示具有前导字符和固定精度的浮点数:

    std::cout << std::setprecision(2) << std::fixed << std::setw(7) << std::setfill('.') << price;

然而,当我使用std :: fixed时,我的填充和宽度被拒绝。如何解决?

由于

当前代码:

std::string filename;

std::ifstream is;
do {

    std::cout << "Podaj nazwę pliku do wczytania: " << std::endl;
    std::cin >> filename;
    is.open(filename.c_str());

    if(is.good()) break;
} while(true);

std::string name;
std::string wtf;
unsigned int quantity = 0;
double price = 0;
unsigned int i = 1;

while(is >> quantity >> price >> std::ws && std::getline(is, name)) {
    std::cout << "| ";
    std::cout << std::setw(2) << i++ << " | ";
    std::cout << std::setw(30) << std::setfill('.') << name << " | ";
    std::cout << std::setw(3) << std::setfill(' ') << quantity << " x ";
    std::cout << std::setprecision(2) << std::setw(10) << std::setfill(' ') << std::fixed << price << " zl | ";
    std::cout << std::setw(11) << std::setfill(' ') << quantity * price << " zl |";
    std::cout << std::endl;
}

该文件如下:

10 12999 TV55AA8000 smarttv ultra HD
5 12990 TV55AB600 smarttv ultraHD
20 9999 TV55GD2340s smarttv
10 7999 TV463400 funkcja 3D
20 1699.5 telewizor super!
30 1400 telewizor 3d 1000Hz
20 12999 telewizor nr 1
30 12000 EE55650 smarttv
10 1000 ED325400s
10 14350.00 EE80234
5 5600.00 TV60ED23231 smart tv plazma
10 2000.00 TV320323
1 12999.00 TV66EE231231 smarttv
12 3400.00 TV4243dss 3D

2 个答案:

答案 0 :(得分:2)

您可以尝试将std::setw(7) << std::setfill('.') <<操纵器放在std::fixed操纵器

之前
std::cout << std::setprecision(2) << std::setw(7) << std::setfill('.') 
          << std::fixed << price;

但至于标准定义,这并不重要。
看起来这可能是您实际工具链的错误。

答案 1 :(得分:1)

要在读取字符串时包含空格,您可以更改空格的定义(是的,可以通过替换新std::ctype<char>中的std::locale方面来完成此 imbue()使用这样构造的std::locale)来流,或者更简单一点,使用std::getline()来读取行的其余部分。假设您要忽略尾随字符前面的前导空格,在格式化和未格式化的输入之间切换时,请使用std::ws

if (std::getline(iss >> quantity >> price >> std::ws, name)) {
    // do something with the result
}

我无法在不进行检查的情况下编写上述输入语句,因为我坚信输入完成后应始终验证输入是否成功。

std::noskipws的目的是禁用格式化输入操作自动跳过空白:格式化输入操作默认跳过前导空格。但是,除了跳过前导空格之外,该标志对如何解析字符串完全没有影响。设置std::noskipws标志后,我认为您只是读取一个空字符串,因为提取会立即找到与格式不匹配的字符并停止。

关于输出的std::fixed设置我非常确定该设置应该有效,但现在我无法验证发生了什么。