اثنان من هياكل TM منفصلة تعكس بعضها البعض
-
27-09-2019 - |
سؤال
ها هو وضعي الحالي:
- لديّان TM ، كلاهما تم تعيينهما على الوقت الحالي
- أقوم بتغيير في الساعة في أحد الهياكل
- التغيير يحدث في الهياكل الأخرى سحرية ....
- كيف يمكنني منع هذا من الحدوث؟ يجب أن أكون قادرًا على مقارنة ومعرفة عدد الثواني بين مرتين مختلفتين - الوقت الحالي والوقت في المستقبل. لقد كنت أستخدم difftime و mktime لتحديد ذلك. أدرك أنني لا أحتاج تقنيًا إلى بنيتين TM (يمكن أن يكون الهيكل الآخر مجرد وقت محمّل بوقت خام) لكنني ما زلت مهتمًا بفهم سبب حدوث ذلك.
Void Tracker :: Monitor (Char* Buffer) {
// time handling
time_t systemtime, scheduletime, currenttime;
struct tm * dispatchtime;
struct tm * uiuctime;
double remainingtime;
// let's get two structs operating with current time
dispatchtime = dispatchtime_tm();
uiuctime = uiuctime_tm();
// set the scheduled parameters
dispatchtime->tm_hour = 5;
dispatchtime->tm_min = 05;
dispatchtime->tm_sec = 14;
uiuctime->tm_hour = 0;
// both of these will now print the same time! (0:05:14)
// what's linking them??
// print the scheduled time
printf ("Current Time : %2d:%02d:%02d\n", uiuctime->tm_hour, uiuctime->tm_min, uiuctime->tm_sec);
printf ("Scheduled Time : %2d:%02d:%02d\n", dispatchtime->tm_hour, dispatchtime->tm_min, dispatchtime->tm_sec);
}
struct tm* Tracker::uiuctime_tm(){
time_t uiucTime;
struct tm *ts_uiuc;
// give currentTime the current time
time(&uiucTime);
// change the time zone to UIUC
putenv("TZ=CST6CDT");
tzset();
// get the localtime for the tz selected
ts_uiuc = localtime(&uiucTime);
// set back the current timezone
unsetenv("TZ");
tzset();
// set back our results
return ts_uiuc;
}
struct tm* Tracker::dispatchtime_tm(){
time_t currentTime;
struct tm *ts_dispatch;
// give currentTime the current time
time(¤tTime);
// get the localtime for the tz selected
ts_dispatch = localtime(¤tTime);
// set back our results
return ts_dispatch;
}
المحلول
انت مجبر على عمل هذا:
struct tm* temp_tm;
struct tm dispatchtime; // No longer a pointer
struct tm uiuctime; // No longer a pointer
temp_tm = dispatchtime_tm();
dispatchtime = *temp_tm; // Member to member copy
temp_tm = uiuctime_tm();
uiuctime = *temp_tm; // Member to member copy
بهذه الطريقة ستحتفظ بنسخة محلية من tm
بنية. يتم تخصيص هذا الهيكل داخليًا في المكتبة القياسية ، كل دعوة إلى localtime
سوف تشير إلى نفس عنوان الذاكرة!
نصائح أخرى
http://www.cplusplus.com/reference/clibrary/ctime/localtime/
يتم تخصيص هذا الهيكل بشكل ثابت ومشاركته من خلال وظائف GMTIME و LocalTime. في كل مرة تسمى إحدى هذه الوظائف محتوى هذا الهيكل.
ستحتاج إلى نسخ القيمة من البنية. يمكن أن تُرجع وظائفك بنية TM حسب القيمة ، ويمكن أن تضعف الوظائف في البرنامج الرئيسي ، إلخ.
ليس لديك في الواقع اثنين من هياكل TM مختلفة على الإطلاق. ما لديك هو اثنين من مؤشرات TM Struct ، وكلاهما يشير إلى نفس الهيكل الثابت الذي تم إرجاعه بواسطة LocalTime. وهكذا يبدو أن التغييرات في أحدهما تؤثر على الآخر ، ولكن في الواقع هو مجرد هيكل واحد له مؤشران مختلفان لها.
الطريقة الأكثر أمانًا لحل هذا هي عدم الاعتماد عليها localtime
بنية ثابتة ، لكن الاستخدام localtime_r
الأمر الذي يتطلب منك أن تمر في مؤشر هيكل TM الخاص بك ، والذي سيتم ملؤه بعد ذلك. فمثلا:
void Tracker::uiuctime_tm(struct tm* out){
time_t uiucTime;
// give currentTime the current time
time(&uiucTime);
// change the time zone to UIUC
putenv("TZ=CST6CDT");
tzset();
// get the localtime for the tz selected, and set back the result into the output parameter.
localtime_r(&uiucTime, out);
// set back the current timezone
unsetenv("TZ");
tzset();
}
struct tm uiuctime;
uiuctime_tm(&uiuctime);