Ir para conteúdo

do function with sprintf


Mohsen

Posts Recomendados

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;

}

Link para o comentário
Compartilhar em outros sites

Hi @Mohsen. Welcome to our community. 🙂

A few things you should consider:

  1. Please edit your current post and format your C code as code by selecting it and clicking the <> button in the text editor. 😉
  2. 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:

  1. 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:
    1. Replace <string> by <string.h>.
    2. Remove <iostream>.
    3. Remove <cstring>.
    4. Remove the using directive.
    5. Don't use string. Use char* instead.
    6. Replace main() by main(void).
  2. 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!

Link para o comentário
Compartilhar em outros sites

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

Editado por fredericopissarra
Link para o comentário
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...