将 int64_t 转换为 C 中的字符串

Converting int64_t to string in C

我正在使用 C 编程语言并使用 Postgres 数据库插入记录。数据库中 table 的其中一列的类型为 timestamp。我在 C 程序中获取的数据是 int64_t 类型,我需要将此值作为参数传递到 INSERT 语句中,如下所示。为此,我尝试使用 sprintf().

int64_t 值转换为字符串
 char str[21];
 sprintf(str, "%" PRId64 "\n", someTimeReceived inTheProgram);  
 const char * const paramValues[1] = { str };

 PGresult *res =     res = PQexecParams(
            conn,
            "INSERT INTO dummy VALUES(1,to_timestamp()::timestamp)",

            1,            /* one parameter */
            NULL,
            paramValues,
            NULL,        /* parameter lengths are not required for strings */
            NULL,        /* all parameters are in text format */
            0            /* result shall be in text format */
        );

但是在使用 sprintf() 时,一些垃圾值被插入到字符串的末尾。例如,如果收到的 int64_t 值为 132408394771256230,则 sprintf() 会将其转换为 132408394771256230\n[=21=][=21=]3。由于在字符串末尾附加了额外的垃圾值,程序无法插入给定值然后终止。

if the received int64_t value is 132408394771256230 then sprintf() is converting it to 132408394771256230\n[=15=][=15=]3

没有,sprintf只将132408394771256230\n[=17=]写入str,其余数组不变,代码3的字符在调用前就存在sprintf(数组未初始化),但当然可以是其他任何东西。

Because of the extra garbage values appended at the end of string, the program fails to insert the given value and then terminates.

不,PQexecParamsparams 管理为字符串数组(在您的情况下为一个字符串),遵循约定字符串结束通过空字符,PQexecParams 不会 read/care 关于空字符之后的内容,甚至知道字符串的 'envelop' (数组在你的情况下是 21 个字符)。

您的问题可能是因为您的字符串中出现了不需要的换行符,导致命令成为字符串

INSERT INTO dummy VALUES(1,to_timestamp(132408394771256230\n)::timestamp)

只需按照 sprintf.

的格式删除 \n

假设需要换行符,您的数组大小必须为 22 而不是 21 才能管理负值,而不会出现未定义的行为写出数组。


...some garbage value

你肯定会看到空字符和后面的字节,因为你使用调试器并且调试器知道 str 的大小为 21,当你要求查看 [=52 的值时=]str 调试器将 str 视为字符数组而不是字符串。如果您要求调试器显示 (char*) str,它会将 str 视为一个字符串,并且不会显示空字符或后面的字符。


[编辑]

函数请求日期时间作为字符串 yyyy-mm-dd hh:mm:ss 而不是你的大数字是 ua_datetime

要将 ua_datetime 转换为预期的字符串,请使用(请参阅 documentation):

nt ua_datetime_snprintf (char * dst, size_t size, const ua_datetime * dt)   

结果是一个字符串 YYYY-MM-DDThh:mm:ss.nnnZ 因此只需将最后一个点替换为空字符并将 'T' 替换为aspace(假设真的产生了a'T',尝试适配)

另一种方法是使用:

time_t ua_datetime_to_time_t(const ua_datetime * dt)    

然后使用 time_t

中的标准函数制作您的字符串

无论如何你必须明白你失去了很多精度,ua_datetime 是 100 纳秒,而 *postgress 时间戳是第二个