C ++将十进制字符串拆分为两个整数

时间:2015-01-09 15:25:44

标签: c++ string converter

给出一个十进制值(秒和分数)作为字符串,如

std::string span = "ssss.nnnn"  // ssss is value in seconds, nnnn is fractional seconds

将它转换为timeval结构(val.ts_sec和val.ts_usec)或timespec结构(tv_sec和tv_nsec)的最佳方法是什么。

大多数答案讨论转换值或不是C ++。有些答案变得非常复杂,或者设置的课程对于这种用法来说实在太多了。

显然,如果两个值由空格分隔,则可以使用sscanf或istringstream。但是,如果它们被"分开,有一种简单的方法可以做到这一点。"没有循环遍历字符缓冲区搜索"。"

4 个答案:

答案 0 :(得分:2)

编辑:正如Borgleader正确提到的那样,如果时间戳变得足够大(大于一百万,给予或接受),简单地读入双精度会导致精度损失。数字稳定的方式是

timeval v;
time_t seconds;
double fraction;

std::istringstream parser(span);

if(parser >> seconds >> std::noskipws >> fraction) {
  v.tv_sec  = seconds;
  v.tv_usec = static_cast<suseconds_t>(fraction * 1e6);
}

从那时起,fraction部分保证足够小,以至于ieee-754 double的尾数将覆盖逗号后的9位以上十进制数字。一个可能的补充是

  v.tv_usec = static_cast<suseconds_t>(fraction * 1e6 + 0.5); // rounding to nearest instead of down

取决于您的使用案例。

答案 1 :(得分:2)

如果你决定使用string类及其功能如果数字总是十进制,那么我会建议以下解决方案:

  string span = "1234.123";
  span += "000000";
  size_t pos = span.find('.');

  struct timeval val;
  val.tv_sec = stol(span.substr(0,pos));
  val.tv_usec = stol(span.substr(pos+1,6));

如果string也可能在没有点的情况下获得整数值。&#39;字符然后使用

  string span = "1234";
  size_t pos = span.find('.');

  struct timeval val;
  val.tv_sec = stol( (pos!=string::npos)? span.substr(0,pos):span );
  val.tv_usec = (pos!=string::npos)? stol((span+"000000").substr(pos+1,6)):0;

此解决方案还使用了一些c ++ 11。

答案 2 :(得分:0)

我刚认为这是一个可能的答案。我还是想找其他的东西。

Parse (split) a string in C++ using string delimiter (standard C++)

  

strtok允许您传递多个字符作为分隔符。我打赌如果   你过去了&#34;&gt; =&#34;您的示例字符串将被正确分割(甚至   虽然&gt;和=被视为单独的分隔符。)

     

编辑如果您不想使用c_str()将字符串转换为字符*,   你可以使用substr和find_first_of进行标记化。

string token, mystring("scott>=tiger");
while(token != mystring){
  token = mystring.substr(0,mystring.find_first_of(">="));
  mystring = mystring.substr(mystring.find_first_of(">=") + 1);
  printf("%s ",token.c_str());
}

<强>更新

@Wintermute指出以下代码片段不起作用,因为可能会导致零。

string span;
int sec;
int usec;
timeval inTime;

sscanf(span.c_str(), "%d.%d", &sec, &usec);
inTime.tv_sec = sec;
inTime.tv_usec = usec;

答案 3 :(得分:0)

您可以使用strtok_s根据分隔符拆分字符串。在你的情况下将是“。”

#include <iostream>
#include <string>

int main()
{
    std::string span = "ssss.nnnn";
    char * span1 = (char *)span.c_str();
    char * pch = NULL;
    char * context;

    pch = strtok_s(span1, " .", &context);

    while (pch != NULL)
    {
        printf("%s\n", pch);
        pch = strtok_s(NULL, " .", &context);
    }

    return 0;
}
  

输出:

     

SSSS

     

NNNN