尝试从命令行获取时间并将其存储在 struct timespec 变量中

Trying to get time from command line and store it in struct timespec variable

我正在尝试从命令行输入纪元格式的时间,我想将它存储在 struct timespec 变量中。

我能够存储它并以某种方式打印它但是当我向 timespec 变量添加一些东西时它给出了奇怪的东西

这是代码

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



int main (int argc, char *argv[]){

    struct timespec InputTime;

    InputTime.tv_sec = (time_t)argv[1]; //(__time_t)
    InputTime.tv_nsec = (long)argv[2]; //(__syscall_slong_t)

    printf("The time before %s,%s\n",
            InputTime.tv_sec,
            InputTime.tv_nsec);

    InputTime.tv_sec += 3;
    InputTime.tv_nsec += 3;

    printf("The time after %s,%s\n",
            InputTime.tv_sec,
            InputTime.tv_nsec);

    return 0;

}

这是输入和输出

INPUT

./InputTime 1615578864 438734073

OUTPUT


The time before 140733952311809,140733952311820
The time after 140733952311812,140733952311823

我曾尝试为 *argv[] 使用其他变量类型,并尝试使用 %s 作为 print 的输出,但之前的时间给了我正确的输入,但之后的时间给了我一些奇怪的东西,这里是当我将 %ld 更改为 %s 时的输出示例。此外,当我这样做时,编译器会给出一些警告,因为我没有使用正确的格式

./InputTime 1615578864 438734073
The time before 1615578864,438734073
The time after 5578864,734073

我正在使用这个 gcc 版本

gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

继续我上面的评论。任何时候您在 C 中读取文本输入(与文件中的二进制输入相反),您读取的是 个字符 而不是数值。当用户输入数字时,它是一串数字,而不是数值。程序员可以使用提供完整错误检测的 strtol() 系列函数或至少使用 sscanf() 来执行从数字串到数值的转换从 succeed/fail 的角度验证转换。

对于您的情况,您可以简单地使用 strtoul() 来为输入值提供最大范围。您只需使用 strtoul()argv[1]argv[2] 转换为数值。最低限度的验证是,例如

    errno = 0;  /* set errno zero before conversion */
    InputTime.tv_sec = strtoul (argv[1], &endptr, 0);   /* convert w/strtoul */
    if (endptr == argv[1] && InputTime.tv_sec == 0) {   /* validate digits converted */
        fputs ("error: no digits converted.\n", stderr);
        return 1;
    }
    else if (errno) {   /* validate no overflow in conversion */
        fputs ("error: overflow in conversion.\n", stderr);
        return 1;
    }

通过两次验证(数字已转换且转换过程中未发生错误)后,您可以确信您的 struct timespec 包含有效输入(您还可以进一步检查转换后的数字是否在使用前的可接受范围)

如果你把它放在一起,你可以这样做:

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

int main (int argc, char *argv[]) {

    struct timespec InputTime;
    char *endptr;
    
    if (argc < 3) {
        fputs ("error: insufficient arguments\n"
            "usage: ./progrm seconds nanoseconds\n", stderr);
        return 1;
    }
    
    errno = 0;  /* set errno zero before conversion */
    InputTime.tv_sec = strtoul (argv[1], &endptr, 0);   /* convert w/strtoul */
    if (endptr == argv[1] && InputTime.tv_sec == 0) {   /* validate digits converted */
        fputs ("error: no digits converted.\n", stderr);
        return 1;
    }
    else if (errno) {   /* validate no overflow in conversion */
        fputs ("error: overflow in conversion.\n", stderr);
        return 1;
    }
    
    errno = 0;  /* set errno zero before conversion */
    InputTime.tv_nsec = strtoul (argv[2], &endptr, 0);   /* convert w/strtoul */
    if (endptr == argv[2] && InputTime.tv_nsec == 0) {   /* validate digits converted */
        fputs ("error: no digits converted.\n", stderr);
        return 1;
    }
    else if (errno) {   /* validate no overflow in conversion */
        fputs ("error: overflow in conversion.\n", stderr);
        return 1;
    }

    printf ("The time before %lu,%09lu\n", InputTime.tv_sec, InputTime.tv_nsec);

    InputTime.tv_sec += 3;
    InputTime.tv_nsec += 3;

    printf ("The time after  %lu,%09lu\n", InputTime.tv_sec, InputTime.tv_nsec);
}

(注:包含了errno.hheader)

例子Use/Output

$ ./bin/inputtime_strtol 1615578864 438734073
The time before 1615578864,438734073
The time after  1615578867,438734076

检查一下,如果您还有其他问题,请告诉我。