Pular para o conteúdo

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

Responder tópico
  • Denunciar
  • Indicar

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

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?

Responder tópico

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

Melhor resposta

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]

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]

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?

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?

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]

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]

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]

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!

Responder tópico

Responder tópico

Entre na sua conta para responder.

Fazer login para responder