0

我正在尝试从命令行以纪元格式输入时间,并且我想将其存储在 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.
4

1 回答 1

1

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

在您的情况下,您可以简单地使用strtoul()为输入值提供最大范围。您只需使用 将argv[1]和转换argv[2]为数值strtoul()。最小验证将是,例如

    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.h标题)

示例使用/输出

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

如果您还有其他问题,请仔细查看并告诉我。

于 2021-03-13T09:50:43.207 回答