Thread: Is that possible? strftime accept a std::string?

  1. #1
    Registered User marcelo.br's Avatar
    Join Date
    Nov 2018
    Posts
    45

    Question Is that possible? strftime accept a std::string?

    I'm trying to make strftime accept a std::string.
    I want to know if it's possible or not to do this conversion!

    OBS I want to alter only strftime

    In the example I did below, he accepts, but is returning an empty value

    Code:
    #include <iostream>
    #include <string>
    
    int main() {
       time_t Capture = time(0);
       std::string Data_Hora;
    
       strftime((char*)Data_Hora.c_str(), 20, "%d/%m/%Y %T", localtime(&Capture)); // 25/05/2020 12:51:00
    
       std::cout << Data_Hora;
    }

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    In the example I did below, he accepts, but is returning an empty value
    Do you realize that std::string.c_str(), returns a const C-string, which means that you can't modify that C-string?

  3. #3
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308
    Code:
    #include "bits/stdc++.h"
    
    
    using namespace std;
    
    
    int main() {
    	time_t Capture = time(0);
    	char d [20];
    	strftime(d, 20, "%c", localtime(&Capture)); // 25/05/2020 12:51:00
    	std::string Data_Hora = d;
    	std::cout << Data_Hora;
    	
    	return 0;
    }
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    There are two problems with your code:
    • The std::string is empty.
    • You're calling c_str(), which returns a const char*, and then casting away the constness, which could be problematic if the original std::string was const to begin with.

    Now, the latter is more of a theoretical problem, but the former is a practical problem because you immediately run into the issue of how to get the std::string to have the space to store the result of strftime. If you try and prefill it with 20 chars, great, but then strftime writes a null terminated string so the operative length would actually be less than 20, whereas the std::string will report its length as 20.

    Consequently, I would suggest that just using a temporary array of char is simplest:
    Code:
    std::string format_time(std::time_t time_value)
    {
        char result[20];
        std::strftime(result, sizeof(result), "%d/%m/%Y %T", std::localtime(&time_value));
        return std::string{result};
    }
    
    // ...
    
    std::string Data_Hora{format_time(time(nullptr))};
    std::cout << Data_Hora;
    
    // ...
    If you really want to directly use a std::string, then you would likely need to construct it with 20 null characters, pass &result[0] instead of c_str() to strftime, then erase the remaining null characters after calling strftime so that the length of the string and the length() member function will align.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User marcelo.br's Avatar
    Join Date
    Nov 2018
    Posts
    45

    Question

    Quote Originally Posted by jimblumberg View Post
    Do you realize that std::string.c_str(), returns a const C-string, which means that you can't modify that C-string?
    I didn't understand what you meant.

    If I put inside strftime a variable char, the strftime passes to my variable the date/time formatted.

    But I'm not getting this when I use std::string
    And when I tried to convert in various ways being the only one that allowed to compile was from above, the variable is not getting any value.

  6. #6
    Registered User marcelo.br's Avatar
    Join Date
    Nov 2018
    Posts
    45
    Quote Originally Posted by Zeus_ View Post
    Code:
    #include "bits/stdc++.h"
    using namespace std;
    int main() {
        time_t Capture = time(0);
        char d [20];
        strftime(d, 20, "%c", localtime(&Capture)); // 25/05/2020 12:51:00
        std::string Data_Hora = d;
        std::cout << Data_Hora;
        return 0;
    }
    That way I know how to do, what I wish is to know or to be able to convert the std::string into the strftime

  7. #7
    Registered User
    Join Date
    Aug 2019
    Location
    inside a singularity
    Posts
    308
    Read laserlight's comment. The c_str() method in your usage is not the way it works or is supposed to work.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning." - Rick Cook, The Wizardry Compiled

  8. #8
    Registered User marcelo.br's Avatar
    Join Date
    Nov 2018
    Posts
    45
    Quote Originally Posted by laserlight View Post
    There are two problems with your code:
    • The std::string is empty.
    • You're calling c_str(), which returns a const char*, and then casting away the constness, which could be problematic if the original std::string was const to begin with.

    Now, the latter is more of a theoretical problem, but the former is a practical problem because you immediately run into the issue of how to get the std::string to have the space to store the result of strftime. If you try and prefill it with 20 chars, great, but then strftime writes a null terminated string so the operative length would actually be less than 20, whereas the std::string will report its length as 20.
    I'm trying to understand your explanation
    So far I just understood that you inform me that I would be deleting the content that String received on strftime
    And that I wouldn't have space in the string to receive the value.

    If you really want to directly use a std::string, then you would likely need to construct it with 20 null characters, pass &result[0] instead of c_str() to strftime, then erase the remaining null characters after calling strftime so that the length of the string and the length() member function will align.
    How could I do this that you inform above? Without creating a char variable, just using std::string imagining that I understand that this is possible by your answer.

  9. #9
    Registered User marcelo.br's Avatar
    Join Date
    Nov 2018
    Posts
    45
    Quote Originally Posted by Zeus_ View Post
    Read laserlight's comment. The c_str() method in your usage is not the way it works or is supposed to work.
    Yes, I am trying to understand, and it seems that the answer is that it is not possible to use std::string, the way I would like. I just really want to be sure.

    What's your answer to that? Is it possible or not?

  10. #10
    Registered User marcelo.br's Avatar
    Join Date
    Nov 2018
    Posts
    45
    Quote Originally Posted by Zeus_ View Post
    Code:
    #include "bits/stdc++.h"
    using namespace std;
    
    int main() {
        time_t Capture = time(0);
        char d [20];
        strftime(d, 20, "%c", localtime(&Capture)); // 25/05/2020 12:51:00
        std::string Data_Hora = d;
        std::cout << Data_Hora;
        return 0;
    }
    I know it's out of the focus of my question, but I'd like to understand from the example you gave above why you used bits/stdc++.h

    Notice that in my example I used
    #include <iostream>
    #include <string>


    So I'd like to know if using as you did is the most ideal, most optimized, with fewer libraries.
    Because it seems that the way I did it is wrong or unnecessary, or exaggerated.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by marcelo.br
    How could I do this that you inform above? Without creating a char variable, just using std::string imagining that I understand that this is possible by your answer.
    Yes, like this:
    Code:
    std::string format_time(std::time_t time_value)
    {
        std::string result(20, '\0');
        std::strftime(&result[0], result.size(), "%d/%m/%Y %T", std::localtime(&time_value));
        result.erase(result.find_first_of('\0'));
        return result;
    }
    But as you can see using a temporary char array is simpler.

    (I should also add a caveat that this approach should only be used if you're compiling with respect to C++11 or later -- which should be the case in 2020 -- as that was when changes to std::string indicated that using &result[0] to directly access the internals of the string object should work... but even then it is still up for some debate and I don't remember the details. To be absolutely safe and compatible with C++03, you would use the old approach of a temporary std::vector<char>, but if you were going to do that, you might as well use a char array here.)

    Quote Originally Posted by marcelo.br
    I know it's out of the focus of my question, but I'd like to understand from the example you gave above why you used bits/stdc++.h
    Zeus_ probably just copied the header inclusion from a test program and forgot to remove it. It is a non-standard convenience header.
    Last edited by laserlight; 05-25-2020 at 07:12 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 06-17-2018, 09:19 PM
  2. Using == to accept string using array
    By libchk in forum C Programming
    Replies: 4
    Last Post: 08-30-2011, 07:13 PM
  3. Accept a string with newline
    By perrrson in forum C Programming
    Replies: 2
    Last Post: 10-22-2010, 01:16 PM
  4. strftime function
    By pv2010 in forum C Programming
    Replies: 1
    Last Post: 04-14-2010, 08:33 AM
  5. Problem with strftime
    By Elemento in forum C Programming
    Replies: 2
    Last Post: 03-02-2005, 06:35 PM

Tags for this Thread