Mohsen Posted December 11, 2022 at 02:18 PM Share Posted December 11, 2022 at 02:18 PM Hey every body! i am trying to do a function with time output (i am beginner) but my code dont work in non form function it is working but when i am trying to convert that as function dont work have any idea? both code are here non function form ------------------------- It work---------------------- #include <stdio.h> /* puts */ #include <time.h> /* time_t, struct tm, time, localtime, strftime */ #include <iostream> using namespace std; int main () { time_t rawtime; struct tm * timeinfo; char buffer [80]; int mili; int dt; dt = 5; mili = dt; rawtime = 1660237353.0; timeinfo = localtime(&rawtime); strftime (buffer,80,"%Y-%m-%d %H:%M:%S",timeinfo); //puts (buffer); char currentTime[84] = ""; sprintf(currentTime, "%s.%03d", buffer,mili); printf("current time: %s \n", currentTime); return 0; } -------------------------------------- functional form which not work _______________ #include <stdio.h> /* puts */ #include <time.h> /* time_t, struct tm, time, localtime, strftime */ #include <string> #include <iostream> #include <cstring> using namespace std; string get_time(double _timstampp, int fraction) { time_t rawtime; struct tm *timeinfo; char buffer [80]; char currentTime[84]; rawtime = _timstampp; timeinfo = localtime(&rawtime); strftime (buffer,80,"%Y-%m-%d %H:%M:%S",timeinfo); sprintf(currentTime, "%s.%03d", buffer,fraction); return currentTime; } int main () { double _timstamp; int dt; dt = 5; _timstamp = 1660237353.0; char* time[84]; //time = get_time(_timstamp,dt); printf("current time: %s \n",get_time(_timstamp,dt)); return 0; } Quote Link to comment Share on other sites More sharing options...
Fernando Mercês Posted December 12, 2022 at 11:51 AM Share Posted December 12, 2022 at 11:51 AM Hi @Mohsen. Welcome to our community. 🙂 A few things you should consider: Please edit your current post and format your C code as code by selecting it and clicking the <> button in the text editor. 😉 To your main problem: you are returning a pointer to a local (stack-allocated) buffer that only exists while get_time() is running. You can't do that. In C, you have a few options: Declare you return variable in the function that calls the desired function (in your case, it'd be in main()) and pass it to the desired function as reference. Here's an example: void get_time(char *currentTime) { // 3. receive the buffer as reference snprintf(currentTime, 80, "%s", "my text"); // 4. write to the buffer } int main(void) { char currentTime[80]; // 1. declare/allocate the buffer before calling the function get_time(_timstamp, dt, currentTime); // 2. pass a reference to the buffer printf("current time: %s \n", currentTime); // 5. buffer contains the string set by get_time() return 0; } As you will notice, I didn't complete the exercise for you. Instead, I've pointed out one way to solve it. 😉 You could also use a global variable or a dynamically-allocated buffer, but your solution depends on what you've studied. If you never studied pointers, then use a global variable. If you didn't study dynamic memory allocation, then use the pointer reference as shown. Other important fixes in your code: You mixed C and C++ headers and functions and this can become very messy very quickly. For example, string is different from char*. Mixing them will thrown errors. So, choose one language and stick with it. In your case, I recommend choosing C. Here's the fixes you need for that: Replace <string> by <string.h>. Remove <iostream>. Remove <cstring>. Remove the using directive. Don't use string. Use char* instead. Replace main() by main(void). sprintf() is insecure and decprecated. Use snprintf() instead. The latter needs the maximum number of characters to write (use the same size you've declared the buffer with). Surely there's more room for improvement, but I'll stop here for now. 🙂 Good luck! Quote Link to comment Share on other sites More sharing options...
fredericopissarra Posted December 12, 2022 at 11:01 PM Share Posted December 12, 2022 at 11:01 PM (edited) One comment of mine on sprintf(), the way it was used above: Notice strftime() will write a 20 chars, including the NUL char, to buffer (which is defined as an array of 80 chars - too much unnecessary chars), and the sprintf(), just below, will write the 19 chars from buffer plus 5 chars (including NUL char), so a 24 chars buffer and currentTime are sufficient... Or, if you want some space to spare, 32, each. This way sprintf() isn't "insecure", and a little bit faster than snprintf(), because the sizes are known. Why the original code using a double as UNIX epoch timestamp is beyond my comprehension ! time_t (defined as a long long int) is more precise (nowadays) than double. To avoid dealing with 2 buffers I would encode the function get_time() as: // Assumes p points to a buffer 24 chars long or more. void get_time_str( char *p, time_t t, int fraction ) { struct tm tm; // thread safe version of localtime() - available o glibc. localtime_r( &t, &tm ); // 4+1+2+1+2+1+2+1+2+1+2+1+3+1= 24 chars! sprintf( p, "%04d-%02d-%02d %02d:%02d:%02d.%03d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, fraction ); } With "d" conversions there is always the possibility we get more then the minimum with or precision given on printf's format string. "%04d" is a MINIMUM of 4 chars long filled with zeros on the left, but if the integer is > 9999, printf will print 5 chars or more! Of course we can avoid this calculating the reminders, as in: sprintf( p, "%04d-%02d-%02d %02d:%02d:%02d.%03d", (tm.tm_year + 1900) % 10000, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, abs(fraction % 1000) ); And we have to make sure the buffer is, at least 25 chars long (because the year component can be negative). Notice I forced fraction to be passed as an absolute (positive) value to avoid adding a '-' char, if, by accident, it is negative. If you don't know how many chars will be "printed" at memory, then sprintf() is, indeed, "unsafe". PS: Since every width and precision with 'd' conversion is a minimal size, the maximum size is of an int, 11 chars for the year (which can be negative) and 10 for the other 6 components, plus se separators and a NUL char: 67 chars (less then 80 or 84). PS2: Fernando is absolutely corrent saying that mixing C with C++ isn't a good idea. And notice the equivalent of string.h is cstring, time.h is ctime, stdio.h is cstdio and stdlib.h is cstdlib, if you insistir on mixing C++ code with C like functions. It is good to know that modern C++ STL (Since C++11) have a namespace std::chrono with templates and functions to deal with date/time. Take a look at cppreference site. []s Fred Edited December 12, 2022 at 11:02 PM by fredericopissarra Quote Link to comment Share on other sites More sharing options...
Mohsen Posted December 13, 2022 at 04:20 PM Author Share Posted December 13, 2022 at 04:20 PM Thank you very Much! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.