C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

1. C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 25/05/2020 - 12:20h

Existe alguma forma de eu conseguir fazer o strftime aceitar minha variável string? Modificando apenas o comando strftime?
Entendi que ele não está aceitando a String, porque strftime pede char *ptr
std::string Registered;
strftime(Registered, 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime));

Erro apresentado
Contacts.cpp:1216:13: error: cannot convert ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’} to ‘char*’
1216 | strftime(Registered, 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime));
| ^~~~~~~~~~
| |
| std::string {aka std::__cxx11::basic_string<char>}

Montei um pequeno exemplo, Assim até compila, mas ele não retorna nada na variável! OBS é C++ não C, e não quero usar variável char.... Apenas lembrando que o meu problema está apenas em modificar o strftime
#include <iostream>
#include <string>
int main() {
time_t Capture = time(0); // Pego Data/Hora Atual
std::string Data_Hora;

//strftime(Registered.c_str(), 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime)); // error: invalid conversion from ‘const char*’ to ‘char*’
//strftime(Registered.data.str().c_str(), 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime)); // error: invalid use of member function ‘const _CharT*

strftime((char*)Data_Hora.c_str(), 20, "%d/%m/%Y %T", localtime(&Capture)); // RESULTADO = 08/04/2019 20:57:13
std::cout << Data_Hora;
}

Eu sei que posso adicionar mais linhas para fazer funcionar, mas o que eu DESEJO é modificar dentro do comando strftime
Como não sou experiente, quero saber se é possível modificar o comando strftime de modo que ele aceite minha variável string como tentei acima mas não serviu! Existe alguma outra forma de formatar ou converter?


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 26/05/2020 - 22:04h

Em lugar de std::strftime(), você pode usar std::put_time(), que funciona de maneira análoga, só que direcionando para um objeto de alguma classe derivada de std::ostream.

#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

int main(){
std::time_t now=time(nullptr);
std::tm tmnow=*localtime(&now);

// Exemplo 1: jogando a hora diretamente na saída.
std::cout << std::put_time(&tmnow, "%Y/%m/%d %H:%M:%S %z") << '\n';

// Exemplo 2: jogando a hora num ostringstream (stream que alimenta um buffer interno que
// é uma string), e depois extraindo o conteúdo do buffer.
std::ostringstream time_stamp;
time_stamp << std::put_time(&tmnow, "%Y/%m/%d %H:%M:%S %z");
std::cout << time_stamp.str() << '\n';

// Exemplo 3: usando um objeto ostringstream temporário, e movendo seu conteúdo para uma
// string comum.
std::string ts(dynamic_cast<std::ostringstream &>((std::ostringstream() << std::put_time(&tmnow, "%Y/%m/%d %H:%M:%S %z"))).str());
std::cout << ts << '\n';
}



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)

3. Re: C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 29/05/2020 - 00:11h

Paulo obrigado por esse enriquecedor exemplo, não conhecia o put_time.
Eu fiz uma correção no exemplo que vc deixou, ao menos me pareceu o certo, me corrija se o que fiz é correto ou se ainda não aprendi a enxergar direito algumas coisas.

Removi alguns includes que entendi que não são necessários. E o compilador compilou normalmente sem apresentar nenhum erro. Compilei assim:
g++ Test.cpp -o Test -O3 -Wall -pedantic -pedantic-errors -Werror
#include <iomanip> // put_time
#include <iostream> // cout
//#include <ctime> // REMOVI
//#include <sstream> // REMOVI
//#include <string> // REMOVI

Já no Exemplo 3 essa linha não compila, mas ainda não tenho capacidade para entender o que o compilador quis dizer pra mim.
Eu tentei colocar dynamic_cast << std::ostringstream mas vi que não tinha nada a ver isso
Tentei inverter dynamic_cast>std::ostringstream mas óbvio que não deu em nada
Tentei fechar o SINAL dynamic_cast<std::ostringstream> mas não aceitou também
Ou seja, não sou capaz de consertar!
// Exemplo 3: usando um objeto ostringstream temporário, e movendo seu conteúdo para uma string comum.
std::string ts(dynamic_cast<std::ostringstream((std::ostringstream() << std::put_time(&tmnow, "%Y/%m/%d %H:%M:%S %z"))).str());

ERROR
Test.cpp:40:48: error: expected ‘>’ before ‘(’ token
40 | std::string ts(dynamic_cast<std::ostringstream((std::ostringstream() << std::put_time(&tmnow, "%Y/%m/%d %H:%M:%S %z"))).str());
| ^

Eu entendi dessa linha: std::string ts
Vc criou uma variável ts e colocou um comando dentro dela que claro cria o valor pronto!
Entendi: << std::put_time(&tmnow, "%Y/%m/%d %H:%M:%S %z"))).str()
Que vc executa o put_time converte ele com .str() enviando o put_time para std::ostringstream()

E não consegui resolver o problema pq não entendi o pedaço, sei que vc fala que isso seria um ostringstream temporário: dynamic_cast<std::ostringstream
Eu entendi que também seja um tipo de conversão para dynamic_cast para que seja aceito em ts




4. Re: C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

Adriano Siqueira
adrisiq

(usa Linux Mint)

Enviado em 29/05/2020 - 10:56h

Tente assim:
std::string Registered;
strftime(Registered.c_str(), 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime));



5. Re: C++ Colocar uma String dentro de strftime? É possível?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 29/05/2020 - 22:18h

adrisiq escreveu:

Tente assim:
std::string Registered;
strftime(Registered.c_str(), 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime));


Salve, AdriSiq.

Essa construção é inválida. O valor retornado por std::string::c_str() é um ponteiro para dados constantes, então não pode ser diretamente usado como argumento de um parâmetro que exige um ponteiro para dados não-constantes. Além disso, supostamente um objeto do tipo std::string que ainda não foi populado com pelo menos 29 caracteres não pode ser seguramente usado para escrever, na marra, 28+1 caracteres (28 com dados e um byte nulo).

Dá para fazer algo como você tentou fazer? Dá. Provavelmente se pareceria com o seguinte.

// NÃO USE!!  ESTE É UM MAU EXEMPLO.  Além disso, eu não o testei, nem vou testar.  É um mau exemplo!
time_t now=time(nullptr);
std::string mau_exemplo(29, '\0');
strftime(const_cast<char *>(mau_exemplo.c_str()), meu_exemplo.length(), "%Y/%m/%d %H:%M:%S", localtime(&now));
mau_exemplo.erase(mau_exemplo.find('\0')).shrink_to_fit();


Mas acredite: você não quer usar esse mau exemplo.


... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


6. Re: C++ Colocar uma String dentro de strftime? É possível?

Paulo
paulo1205

(usa Ubuntu)

Enviado em 29/05/2020 - 22:25h

Nick-us escreveu:

Paulo obrigado por esse enriquecedor exemplo, não conhecia o put_time.
Eu fiz uma correção no exemplo que vc deixou, ao menos me pareceu o certo, me corrija se o que fiz é correto ou se ainda não aprendi a enxergar direito algumas coisas.

Removi alguns includes que entendi que não são necessários. E o compilador compilou normalmente sem apresentar nenhum erro. Compilei assim:
g++ Test.cpp -o Test -O3 -Wall -pedantic -pedantic-errors -Werror
#include <iomanip> // put_time
#include <iostream> // cout
//#include <ctime> // REMOVI
//#include <sstream> // REMOVI
//#include <string> // REMOVI


Você não deveria ter removido nenhum deles. Ainda que funcione no seu computador, com o compilador que você usa, não tem garantia nenhuma de funcionará em outros. std::ostringstream é declarado em <sstream>, std::time_t e std::tm são definidos em <ctime>, e std::string é declarada em <string>. Então, a boa prática recomende que você os liste.

Já no Exemplo 3 essa linha não compila, mas ainda não tenho capacidade para entender o que o compilador quis dizer pra mim.
Eu tentei colocar dynamic_cast << std::ostringstream mas vi que não tinha nada a ver isso
Tentei inverter dynamic_cast>std::ostringstream mas óbvio que não deu em nada
Tentei fechar o SINAL dynamic_cast<std::ostringstream> mas não aceitou também
Ou seja, não sou capaz de consertar!


De fato, não sei por que, já que a cópia que eu tinha aqui em casa e que foi de onde eu copiei para a postagem está correta, faltaram três caracteres (um espaço e “&>”) na transcrição. Já corrigi a postagem original.


... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


7. Re: C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 29/05/2020 - 23:26h

adrisiq escreveu: Tente assim:
std::string Registered;
strftime(Registered.c_str(), 29, "%d/%m/%Y %H:%M", localtime(&CaptureTime));

Boa Noite, na pergunta que fiz, se vc observar eu informei que tentei dessa forma e não funcionou, e no comentário mostro o erro que gera! No exemplo que deixei na pergunta esse teste está comentado, justamente porque não funciona.



8. Re: C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 29/05/2020 - 23:30h

paulo1205 escreveu:
// NÃO USE!!  ESTE É UM MAU EXEMPLO.  Além disso, eu não o testei, nem vou testar.  É um mau exemplo!
time_t now=time(nullptr);
std::string mau_exemplo(29, '\0');
strftime(const_cast<char *>(mau_exemplo.c_str()), meu_exemplo.length(), "%Y/%m/%d %H:%M:%S", localtime(&now));
mau_exemplo.erase(mau_exemplo.find('\0')).shrink_to_fit();

Mas acredite: você não quer usar esse mau exemplo.

Eu vi uma solução assim também na Internet, mas a princípio nem gostei dela, pq eu estaria declarando a Qtd de Caracteres o que não seria diferente de declarar um char de forma padrão.
Mas o que vc acrescentou como má prática, é importante, porque agora também sei que não é bom usar assim!



9. Re: C++ Colocar uma String dentro de strftime? É possível? [RESOLVIDO]

Nick Us
Nick-us

(usa Slackware)

Enviado em 29/05/2020 - 23:34h

paulo1205 escreveu:
Você não deveria ter removido nenhum deles. Ainda que funcione no seu computador, com o compilador que você usa, não tem garantia nenhuma de funcionará em outros. std::ostringstream é declarado em <sstream>, std::time_t e std::tm são definidos em <ctime>, e std::string é declarada em <string>. Então, a boa prática recomende que você os liste.

Outra informação bastante útil! Que eu não tinha como atenção! Eu não sabia que o compilador, por um motivo ou outro, poderia tratar essas declarações. Eu uso o gcc no Linux. É bom estar atento a isso!







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts