我可以使用 stringstream 判断 std::string 是否表示数字吗?

发布于 2024-10-16 07:13:32 字数 255 浏览 8 评论 0原文

显然,这应该用于显示字符串是否是数字,例如“12.5”==是,“abc”==否。然而,无论输入如何,我都会得到一个结果。

std::stringstream ss("2");
double d; ss >> d;
if(ss.good()) {std::cout<<"number"<<std::endl;}
else {std::cout<<"other"<<std::endl;}

Apparently this is suposed to work in showing if a string is numerical, for example "12.5" == yes, "abc" == no. However I get a no reguardless of the input.

std::stringstream ss("2");
double d; ss >> d;
if(ss.good()) {std::cout<<"number"<<std::endl;}
else {std::cout<<"other"<<std::endl;}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半仙 2024-10-23 07:13:32

不要使用good()!测试流是否失败

if (ss)

Good 告诉您是否设置了 eofbit、badbit 或 failurebit,而fail() 告诉您有关 badbit 和 failurebit 的信息。你几乎从不关心 eofbit,除非你已经知道流失败了,所以你几乎不想使用 good。

请注意,如上所述,直接测试流完全等同于:

if (!ss.fail())

相反,!ss 等同于 ss.fail()。


将提取组合到条件表达式中:

if (ss >> d) {/*...*/}

完全等同于:

ss >> d;
if (ss) {/*...*/}

但是,您可能想测试完整的字符串是否可以转换为双精度型,这有点复杂。使用已经处理所有情况的 boost::lexical_cast 。

Don't use good()! Test if the stream is failed or not:

if (ss)

Good tells you if any of eofbit, badbit, or failbit are set, while fail() tells you about badbit and failbit. You almost never care about eofbit unless you already know the stream is failed, so you almost never want to use good.

Note that testing the stream directly, as above, is exactly equivalent to:

if (!ss.fail())

Conversely, !ss is equivalent to ss.fail().


Combining the extraction into the conditional expression:

if (ss >> d) {/*...*/}

Is exactly equivalent to:

ss >> d;
if (ss) {/*...*/}

However, you probably want to test if the complete string can be converted to a double, which is a bit more involved. Use boost::lexical_cast which already handles all of the cases.

小矜持 2024-10-23 07:13:32

如果您想检查字符串是否包含一个数字而没有其他内容(除了空格),请使用:

#include <sstream>

bool is_numeric (const std::string& str) {
    std::istringstream ss(str);
    double dbl;
    ss >> dbl;      // try to read the number
    ss >> std::ws;  // eat whitespace after number

    if (!ss.fail() && ss.eof()) {
        return true;  // is-a-number
    } else {
        return false; // not-a-number
    }
}

ss >> std::ws 对于接受带有尾随空格的数字(例如 "24 ")非常重要。

ss.eof() 检查对于拒绝像 "24 abc" 这样的字符串非常重要。它确保我们在读取数字(和空格)后到达字符串的末尾。

测试工具:

#include <iostream>
#include <iomanip>

int main()
{
    std::string tests[8] = {
            "", "XYZ", "a26", "3.3a", "42 a", "764", " 132.0", "930 "
    };
    std::string is_a[2] = { "not a number", "is a number" };
    for (size_t i = 0; i < sizeof(tests)/sizeof(std::string); ++i) {
        std::cout << std::setw(8) << "'" + tests[i] + "'" << ": ";
        std::cout << is_a [is_numeric (tests[i])] << std::endl;
    }
}

输出:

      '': not a number
   'XYZ': not a number
   'a26': not a number
  '3.3a': not a number
  '42 a': not a number
   '764': is a number
' 132.0': is a number
  '930 ': is a number

If you want to check whether a string contains only a number and nothing else (except whitespace), use this:

#include <sstream>

bool is_numeric (const std::string& str) {
    std::istringstream ss(str);
    double dbl;
    ss >> dbl;      // try to read the number
    ss >> std::ws;  // eat whitespace after number

    if (!ss.fail() && ss.eof()) {
        return true;  // is-a-number
    } else {
        return false; // not-a-number
    }
}

The ss >> std::ws is important for accepting numbers with trailing whitespace such as "24 ".

The ss.eof() check is important for rejecting strings like "24 abc". It ensures that we reached the end of the string after reading the number (and whitespace).

Test harness:

#include <iostream>
#include <iomanip>

int main()
{
    std::string tests[8] = {
            "", "XYZ", "a26", "3.3a", "42 a", "764", " 132.0", "930 "
    };
    std::string is_a[2] = { "not a number", "is a number" };
    for (size_t i = 0; i < sizeof(tests)/sizeof(std::string); ++i) {
        std::cout << std::setw(8) << "'" + tests[i] + "'" << ": ";
        std::cout << is_a [is_numeric (tests[i])] << std::endl;
    }
}

Output:

      '': not a number
   'XYZ': not a number
   'a26': not a number
  '3.3a': not a number
  '42 a': not a number
   '764': is a number
' 132.0': is a number
  '930 ': is a number
墨落成白 2024-10-23 07:13:32

您应该使用 istringstream 以便它知道它正在尝试解析输入。另外,直接检查提取的结果,而不是稍后使用good

#include <sstream>
#include <iostream>

int main()
{
    std::istringstream ss("2");
    double d = 0.0;
    if(ss >> d) {std::cout<<"number"<<std::endl;}
    else {std::cout<<"other"<<std::endl;}
}

You should use an istringstream so that it knows it's trying to parse input. Also, just check the result of the extraction directly rather than using good later.

#include <sstream>
#include <iostream>

int main()
{
    std::istringstream ss("2");
    double d = 0.0;
    if(ss >> d) {std::cout<<"number"<<std::endl;}
    else {std::cout<<"other"<<std::endl;}
}
中二柚 2024-10-23 07:13:32
int str2int (const string &str) {
  stringstream ss(str);
  int num;
  if((ss >> num).fail())
  { 
      //ERROR: not a number
  }
  return num;
}
int str2int (const string &str) {
  stringstream ss(str);
  int num;
  if((ss >> num).fail())
  { 
      //ERROR: not a number
  }
  return num;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文