负时间转换给出随机值
Negative time conversion gives random values
我正在尝试计算 C 中两个时间点之间的差异,因为这些时间点在 1900 年之前,所以我需要使用负值。
虽然转换应该将变量 jahr_tod_negative
写入 ts.tm_year
,但几乎每次我 运行 程序,它都会给我一个完全不同的日期,甚至日和月混淆了。年份是唯一需要为负数的值。我怎样才能避免这种情况?
#include <stdio.h>
#include <time.h>
int main ()
{
time_t t;
struct tm ts;
char str[90];
int tag_tod;
int monat_tod;
int jahr_tod;
unsigned int jahr_tod_von_1900;
int jahr_tod_negative;
printf("Tag eingeben: ");
scanf("%d", &tag_tod);
printf("\nMonat eingeben: ");
scanf("%d", &monat_tod);
printf("\nJahr eingeben: ");
scanf("%d", &jahr_tod);
jahr_tod_von_1900 = 1900 - jahr_tod;
jahr_tod_negative = -jahr_tod_von_1900;
printf("jahr_tod_negative: %d\n", jahr_tod_negative);
//ts.tm_sec = 0;
//ts.tm_min = 0;
//ts.tm_hour = 0;
ts.tm_mday = tag_tod;
ts.tm_mon = monat_tod;
ts.tm_year = jahr_tod_negative; /* Jahr - 1900 */
//ts.tm_wday = 0;
//ts.tm_yday = 0;
//ts.tm_isdst = 0;
t = mktime(&ts);
//printf("%s", asctime(&ts));
printf("ts.tm_year: %d\n", ts.tm_year);
strftime(str, 90, "%d. %B %Y", &ts);
printf("Eingegebenes Datum: %s\n", str);
return 0;
}
问题(可能还有其他问题)在于
jahr_tod_von_1900 = 1900 - jahr_tod;
你声明的地方:
unsigned int jahr_tod_von_1900;
如果 jahr_tod
实际上大于 1900
会怎样?您隐式地将负值转换为无符号整数,因此通常会得到一个非常大的值。
如果我扔掉所有 jahr_tod_negative 东西,只使用(一次!)
ts.tm_year = jahr_tod - 1900;
我总能得到正确答案。
对于初学者:您想正确初始化
struct tm ts;
在使用之前。否则代码很可能 运行 变成 未定义的行为 ,所以任何事情都可能发生。
做
struct tm ts = {0};
至少。
进一步假设
unsigned int jahr_tod_von_1900;
int jahr_tod_negative;
此声明
jahr_tod_von_1900 = 1900 - jahr_tod;
导致 signed
整数环绕 jahr_tod > 1900
。后者 "overflow" 也会导致 未定义的行为 。 不要这样做。
当你分配给一个 unsigned
时,要解决这个问题,请确保你做一个 "unsigned" 减法,例如这样:
jahr_tod_von_1900 = 1900U - (unsigned int) jahr_tod;
我正在尝试计算 C 中两个时间点之间的差异,因为这些时间点在 1900 年之前,所以我需要使用负值。
虽然转换应该将变量 jahr_tod_negative
写入 ts.tm_year
,但几乎每次我 运行 程序,它都会给我一个完全不同的日期,甚至日和月混淆了。年份是唯一需要为负数的值。我怎样才能避免这种情况?
#include <stdio.h>
#include <time.h>
int main ()
{
time_t t;
struct tm ts;
char str[90];
int tag_tod;
int monat_tod;
int jahr_tod;
unsigned int jahr_tod_von_1900;
int jahr_tod_negative;
printf("Tag eingeben: ");
scanf("%d", &tag_tod);
printf("\nMonat eingeben: ");
scanf("%d", &monat_tod);
printf("\nJahr eingeben: ");
scanf("%d", &jahr_tod);
jahr_tod_von_1900 = 1900 - jahr_tod;
jahr_tod_negative = -jahr_tod_von_1900;
printf("jahr_tod_negative: %d\n", jahr_tod_negative);
//ts.tm_sec = 0;
//ts.tm_min = 0;
//ts.tm_hour = 0;
ts.tm_mday = tag_tod;
ts.tm_mon = monat_tod;
ts.tm_year = jahr_tod_negative; /* Jahr - 1900 */
//ts.tm_wday = 0;
//ts.tm_yday = 0;
//ts.tm_isdst = 0;
t = mktime(&ts);
//printf("%s", asctime(&ts));
printf("ts.tm_year: %d\n", ts.tm_year);
strftime(str, 90, "%d. %B %Y", &ts);
printf("Eingegebenes Datum: %s\n", str);
return 0;
}
问题(可能还有其他问题)在于
jahr_tod_von_1900 = 1900 - jahr_tod;
你声明的地方:
unsigned int jahr_tod_von_1900;
如果 jahr_tod
实际上大于 1900
会怎样?您隐式地将负值转换为无符号整数,因此通常会得到一个非常大的值。
如果我扔掉所有 jahr_tod_negative 东西,只使用(一次!)
ts.tm_year = jahr_tod - 1900;
我总能得到正确答案。
对于初学者:您想正确初始化
struct tm ts;
在使用之前。否则代码很可能 运行 变成 未定义的行为 ,所以任何事情都可能发生。
做
struct tm ts = {0};
至少。
进一步假设
unsigned int jahr_tod_von_1900;
int jahr_tod_negative;
此声明
jahr_tod_von_1900 = 1900 - jahr_tod;
导致 signed
整数环绕 jahr_tod > 1900
。后者 "overflow" 也会导致 未定义的行为 。 不要这样做。
当你分配给一个 unsigned
时,要解决这个问题,请确保你做一个 "unsigned" 减法,例如这样:
jahr_tod_von_1900 = 1900U - (unsigned int) jahr_tod;