C - 将子字符串转换为int

时间:2015-12-02 22:44:48

标签: c type-conversion

目前我在C中使用这个简单的代码将天,分和秒转换为仅秒:

已编辑(我理解atoi的问题,这样可以纠正吗?):

#include <stdio.h>
#include <stdlib.h>

int getseconds(char * time)
{
    int seconds=0, i=0;
    char buffer[3];
    while (*time != '\0')
    {
        switch (*time)
        {
            case 'h': buffer[i]='\0';i=0;seconds=seconds+atoi(buffer)*3600;break;
            case 'm': buffer[i]='\0';i=0;seconds=seconds+atoi(buffer)*60;break;
            case 's': buffer[i]='\0';i=0;seconds=seconds+atoi(buffer);break;
            case ' ':break;
            default: buffer[i]=*time;i++;break;
        }
        time++;
    }
    return seconds;
}

int main()
{

    char *time = "12h  4m 58s";
    int seconds = getseconds(time);
    printf("%d",seconds);
    return 0;
}

这是我想要的,但没有其他方法可以做到这一点,而没有创建更多的变量(比如C#,我只需转换&#34;内联&#34; .C只有函数吗?转换为变量而不是&#34;内联&#34;)?

C#示例:

        string time = "12h 34m 58s";
        int seconds = int.Parse(time.Substring(0, 2)) * 3600 + int.Parse(time.Substring(4, 2)) * 60 + int.Parse(time.Substring(8, 2));

你可以发现我猜的行数差异:)。

3 个答案:

答案 0 :(得分:4)

您可以使用atoi()strtol()来完成这项工作。您不需要首先提取子字符串,因为这些函数会在第一个无法转换的字符处停止。您只需要对字符串的开始位置进行不同的视图。因此,此代码非常类似于您的C#示例:

int getseconds(const char * time) {
    return atoi(time) * 3600 + atoi(time + 4) * 60 + atoi(time + 8);
}

当然它会破坏一些格式错误的输入,但C#也是如此(虽然不是所有相同的输入)。

答案 1 :(得分:2)

使用sscanf()检测扫描结束的

"%n"已关闭,但确实使用了更多变量。

int getseconds2(const char * time) {
   int h,m,s;
   int n = 0;
   sscanf(time, "%d h%d m%d s %n", &h,&m, &s, &n);
   if (n == 0 || time[n] != '\0') return -1;  // failure
   return h*3600 + m *60 + s;
}

"%n"可以保存扫描的字符数。因为在格式的末尾使用,所以测试它是否为非零(原始值)并且time以空字符结束,以确保扫描的完整性。

@chqrlie建议错误匹配C#功能。

   // to match C#
   if (n == 0) return -1;  // failure

答案 2 :(得分:1)

更简单的解决方案是可能的:

int getseconds( const char* time)
{
    int h, m, s = 0 ;
    char sdelim = 0 ;
    int check = sscanf( time, "%dh %dm %d%c", &h, &m, &s, &sdelim ) ;
    if( check == 3 && sdelim = 's' )
    {
        s = ((h * 60) + m) * 60 + s ;
    }

    return s ;
}