const
(только для C ++) Для людей, прибывающих с C, может показаться неожиданным, что в C ++ глобальные переменные const
имеют внутренние (или статические) связь. В C это не так, поскольку все глобальные переменные неявно extern
(т.е. когда отсутствует ключевое слово static
).
Пример:
// file1.cpp
const int test = 5; // in C++ same as "static const int test = 5"
int test2 = 5;
// file2.cpp
extern const int test;
extern int test2;
void foo()
{
int x = test; // linker error in C++ , no error in C
int y = test2; // no problem
}
correct would использовать файл заголовка и включить его в file2.cpp и file1.cpp
extern const int test;
extern int test2;
. В качестве альтернативы можно было бы объявить переменную const
в файле file1.cpp с явным extern
Данные не будут сохраняться между двумя вызовами localtime
или asctime
. Вы должны где-то копировать данные. Вот исправленный пример (по-прежнему у вас мало проблем с strncpy):
#include <stdio.h>
#include <time.h>
#include <string.h>
int main() {
time_t time1, time2;
struct tm timeinfo1, timeinfo2, *ti;
char time1str[256], time2str[256], *tstr;
time1 = 3600;
time2 = 3720;
ti = localtime(&time1);
memcpy(&timeinfo1, ti, sizeof(*ti));
ti = localtime(&time2);
memcpy(&timeinfo2, ti, sizeof(*ti));
tstr = asctime(&timeinfo1);
strncpy(time1str, tstr, sizeof(time1str) - 1);
tstr = asctime(&timeinfo2);
strncpy(time2str, tstr, sizeof(time1str) - 1);
puts(time1str);
puts(time2str);
return 0;
}
localtime()
и asctime()
каждый возвращает указатель на внутренний буфер. Этот буфер перезаписывается каждый раз, когда вызывается localtime()
или asctime()
, поэтому в коде OP результат первого вызова заменяется результатом второго вызова.
Чтобы иметь разное время, напечатанное просто измените порядок вызовов следующим образом:
timeinfo1 = localtime(&time1);
time1str = asctime(timeinfo1);
puts(time1str);
timeinfo2 = localtime(&time2);
time2str = asctime(timeinfo2);
puts(time2str);
Альтернативно, если вы используете систему, совместимую с POSIX, используйте localtime_r()
и asctime_r()
, которые используют буфер, предоставленный вызывающим:
#define _POSIX_C_SOURCE 1
#include<stdio.h>
#include<conio.h>
#include<time.h>
int main(void)
{
time_t time1 = 3600;
time_t time2 = 3720;
struct tm timeinfo1 = {0};
struct tm timeinfo2 = {0};
char time1str[32] = "";
char time2str[32] = "";
localtime_r(&time1, &timeinfo1);
localtime_r(&time2, &timeinfo2);
asctime_r(&timeinfo1, timestr1);
asctime_r(&timeinfo2, timestr2);
puts(time1str);
puts(time2str);
getch();
return 0;
}
Обратите внимание на различное объявление переменных timeinfo?
и time?str
.
Из doc localtime :
Возвращаемое значение указывает на внутренний объект, срок действия которого или значение которого может быть изменен любым последующим вызовом gmtime или localtime.
blockquote>
localtime()
возвращает дважды тот же указатель: вы работаете дважды по тем же данным.Тест:
printf("%p\n", localtime(&time1)); printf("%p\n", localtime(&time2));
Выход:
0x7f7d9d2eee80 0x7f7d9d2eee80
Почему ... console показывает 2 равных дат?
blockquote>
localtime()
иgmtime()
возвращает указатель на общую папку памятиstruct tm
.Как @keltar хороший ответ, чтобы сохранить информацию
struct tm
, код должен скопировать этоstruct tm
перед последующим вызовомlocaltime(), gmtime()
.Вместо
mempcy()
будет выполнено простое присваивание=
.// struct tm *timeinfo1, *timeinfo2; // Not pointers struct tm timeinfo1, timeinfo2; // ... but structures. time1 = 3600; time2 = 3720; // timeinfo1 = localtime(&time1); // Rather than copy the pointer // timeinfo2 = localtime(&time2); // v--------------------- // Notice the * timeinfo1 = *localtime(&time1); // Copy the structure timeinfo2 = *localtime(&time2);