1

我不明白为什么以下代码返回*end=='\0\'

bool isValue(const string &token,int &output_value) //czy string jest wartoscia
{
  char *end = 0;
  errno=0;
  output_value = strtol(token.c_str(),&end,10); //converts string to int
  if (errno!=0) return false;
  return *end=='\0';
}

编辑:和愚蠢的问题,但我不知道为什么有

bool isValue(const string &token,int &output_value)

代替

bool isValue(string &token,int &output_value)

bool isValue(string token,int output_value)
4

4 回答 4

3

建议使用 stringstream 会不会错?

#include <sstream>
#include <string>

using namespace std;

bool isValue(const string &input, int &output)
{
    stringstream ss;
    ss << input;
    return(ss >> output)
}
于 2012-08-21T15:15:54.783 回答
2

strtol可以将全局变量设置errno为某些代码。http://cplusplus.com/reference/clibrary/cstdlib/strtol/

如果正确值超出可表示值的范围,则返回 LONG_MAX 或 LONG_MIN,并将全局变量 errno 设置为 ERANGE。

如果端点在 '\0' (字符串结尾)上,则您的函数返回 true,否则返回 false。

最后,指向 str 中整数表示之后的第一个字符的指针存储在 endptr 指向的对象中

于 2012-08-21T14:58:04.467 回答
1

errno是一个旧的 C hack。它是一个全局变量(今天是线程本地的)。 strtol如果存在(检测到)错误,则将其设置为非零值(如果没有错误,或者其原始值不为 0,则保持不变 - 它的设计目的是您可以链接多个调用,并且只检查在末尾)。

请注意,有问题的代码是错误的。(我知道是因为我最近犯了同样的错误。委婉地说,strtolin case of error 的语义很奇怪。)你需要这样的东西:

bool
intValue( std::string const& token, int& toReturn )
{
    char* end = NULL;
    char const* s = token.c_str();
    errno = 0;
    long results = strtol( s, &end, 10 );
    bool error = errno != 0
        || end != s
        || *end == '\0'
        || results <= std::numeric_limits<int>::max()
        || results >= std::numeric_limits<int>::min();
    if ( !error ) {
        toReturn = results;
    }
    return error;
}

请注意,1)您必须确保end != s;和 2)您必须检查结果是否要写入int. WRT 第一个,规范strtol说如果它没有找到任何要转换的字符(即字符串不包含任何数字),它返回 0,设置end为字符串的开头,并且不修改 errno.

于 2012-08-21T15:05:31.447 回答
0

errno部分可能是遗留代码。它可能在某个时候被使用过,但使用它的代码可能已被删除,但却errno被遗忘了。你是对的,它什么都不做,可能会被优化。<--- 认为errno是一个局部变量(隐形编辑?)

end

指向 str 中整数表示之后的第一个字符的指针存储在 endptr 指向的对象中。

所以基本上条件检查数字后面的字符串中是否有任何其他字符。

于 2012-08-21T14:58:36.557 回答