intToStr

Discussion in 'C Programming' started by Andrej Viktorovich, Jun 29, 2012.

  1. Hello,

    Moving from delphi to C :)

    Got garbage on output while converting integer to C string. Have feeling that something wrong with char* on intToStr return. What is the right way of doing that?

    char* intToStr(int value)
    {
    char buffer[33];
    char* c;
    c= itoa(value,buffer,10);
    return buffer;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {

    cout<<intToStr(55)<<"\n";

    getc(stdin);

    return 0;
    }

    Thank you
    Andrej Viktorovich, Jun 29, 2012
    #1
    1. Advertising

  2. Andrej Viktorovich

    Mark Bluemel Guest

    On 29/06/2012 13:18, Andrej Viktorovich wrote:
    > Hello,
    >
    > Moving from delphi to C :)


    I don't think so. What you have below looks like C++...

    > Got garbage on output while converting integer to C string. Have
    > feeling that something wrong with char* on intToStr return. What
    > is the right way of doing that?


    Assuming that C++ differs little from C in this respect, you're
    returning the address of a buffer which is local to the invocation of
    intToStr. It's not a good idea.

    >
    > char* intToStr(int value)
    > {
    > char buffer[33];
    > char* c;
    > c= itoa(value,buffer,10);
    > return buffer;
    > }
    >
    > int _tmain(int argc, _TCHAR* argv[])
    > {
    >
    > cout<<intToStr(55)<<"\n";
    >
    > getc(stdin);
    >
    > return 0;
    > }
    >
    > Thank you
    >
    Mark Bluemel, Jun 29, 2012
    #2
    1. Advertising


  3. > Assuming that C++ differs little from C in this respect, you're
    > returning the address of a buffer which is local to the invocation of
    > intToStr. It's not a good idea.
    >



    I have feeling that in C i must create memory area and pass it like parameter to function that converts int to string.

    But I would like to have simple function with one param of integer and I would like to ask intToString to do all that job of creating memory area and I need just char[] on utput. Is it possible to think that way in C?

    Thank you
    Andrej Viktorovich, Jun 29, 2012
    #3
  4. In article <>,
    Andrej Viktorovich <> wrote:
    >
    >> Assuming that C++ differs little from C in this respect, you're
    >> returning the address of a buffer which is local to the invocation of
    >> intToStr. It's not a good idea.
    >>

    >
    >
    >I have feeling that in C i must create memory area and pass it like
    >parameter to function that converts int to string.
    >
    >But I would like to have simple function with one param of integer and I
    >would like to ask intToString to do all that job of creating memory area
    >and I need just char[] on utput. Is it possible to think that way in C?
    >
    >Thank you


    You can usually work around this by making the local buffer static.

    But the problem with that is that your function then becomes not
    "thread-safe" (and also, can't be called recursively).

    --
    "The anti-regulation business ethos is based on the charmingly naive notion
    that people will not do unspeakable things for money." - Dana Carpender

    Quoted by Paul Ciszek (pciszek at panix dot com). But what I want to know
    is why is this diet/low-carb food author doing making pithy political/economic
    statements?

    Nevertheless, the above quote is dead-on, because, the thing is - business
    in one breath tells us they don't need to be regulated (which is to say:
    that they can morally self-regulate), then in the next breath tells us that
    corporations are amoral entities which have no obligations to anyone except
    their officers and shareholders, then in the next breath they tell us they
    don't need to be regulated (that they can morally self-regulate) ...
    Kenny McCormack, Jun 29, 2012
    #4
  5. "Andrej Viktorovich" <> schrieb im Newsbeitrag
    news:...
    ....
    > char* intToStr(int value)
    > {
    > char buffer[33];
    > char* c;
    > c= itoa(value,buffer,10);
    > return buffer;
    > }

    ....
    buffer is only valid inside intToStr. After "return buffer;", buffer is
    destroyed. You need "static char buffer[33];" But that is not reentrant!
    When doing similar things, I call intToStr with a buffer supplied by the
    caller.

    char* intToStr(int value, char *buffer)
    {
    itoa(value,buffer,10);
    return buffer;
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    char buffer[33];
    cout<<intToStr(55, buffer)<<"\n";
    getc(stdin);
    return 0;
    }
    Heinrich Wolf, Jun 29, 2012
    #5
  6. Andrej Viktorovich

    Stefan Ram Guest

    Andrej Viktorovich <> writes:
    >But I would like to have simple function with one param of
    >integer


    Do you mean int?

    >and I would like to ask intToString to do all that job of
    >creating memory area and I need just char[] on utput.


    It is better to pass in a buffer of the right size, which
    is some value near LOG10(INT_MAX), say LOG10(INT_MAX)+2
    or so. You get INT_MAX from <limits.h> and still need to
    define LOG10 yourself.

    The called function could allocate a buffer using malloc,
    but management of memory with allocated storage duration
    is more difficult in C.
    Stefan Ram, Jun 29, 2012
    #6
  7. Andrej Viktorovich

    James Kuyper Guest

    On 06/29/2012 08:18 AM, Andrej Viktorovich wrote:
    > Hello,
    >
    > Moving from delphi to C :)
    >
    > Got garbage on output while converting integer to C string. Have feeling that something wrong with char* on intToStr return. What is the right way of doing that?
    >
    > char* intToStr(int value)
    > {
    > char buffer[33];
    > char* c;
    > c= itoa(value,buffer,10);


    itoa() is not a C standard library function. I'll assume, given the
    context, that it fills buffer with a string corresponding to the
    specified value, using base 10?

    > return buffer;
    > }


    The object named buffer has a lifetime that ends when your function
    returns. Dereferencing a pointer that points at an object whose life
    time has ended has undefined behavior. In practical terms, by the time
    your program has a chance to look at the memory pointed at by the
    string, it may already have been reassigned for some other use.

    You have two main options.

    The first is to give buffer static storage duration, which means that
    it's life time extends from the beginning of the program all the way to
    the end of the program; the pointer will remain valid forever. But this
    means that if you call intToStr() twice, the pointer returned by the
    first call will, after the second call, point to the string containing
    the result the second call.

    A second option is to allocate memory for the string using malloc(). The
    lifetime of such memory continues until the memory has been free()d.
    Problem: if you don't free() it, you've got a memory leak. You can't
    free() it unless you stored the pointer somewhere so it can be passed to
    free(), which is not the case in the code below:

    > int _tmain(int argc, _TCHAR* argv[])
    > {
    >
    > cout<<intToStr(55)<<"\n";


    I thought you said you were using C? This looks like C++, a different,
    though closely related language. You'll get better answers about such
    things by going to comp.lang.c++. Among other things, you could use new
    and delete instead of malloc() and free(), and there are smart pointer
    types you can use to avoid the necessity of explicitly using delete,
    though I'm not well qualified to explain those. Also, do you realize
    that you'd get a similar result by writing

    cout << 55 << "\n";

    It would also be more idiomatic to use endl rather than "\n".

    You only need to do complicated things like this when cout() doesn't
    already have the needed overloaded operator<<, for instance when you're
    trying to print out a user defined type (UDT). The idiomatic C++ way to
    handle that problem is to define your own operator<< overload. It should
    take std::eek:stream& as it's first argument, your UDT as the second, and
    it should return its first argument as a reference, so << overloads can
    be chained together.
    --
    James Kuyper
    James Kuyper, Jun 29, 2012
    #7
  8. very helpful reply!
    Heinrich Wolf, Jun 29, 2012
    #8
  9. Thank you, I got many answers to a lot of hypothetical questions.

    But how do you deal in case for example when you need just log some variables like debug info. How you construct string that will be saved to file? Doyou really make such long and boring conversion to string routine (creating char[] variable, calling itoa ) for each variable of a,b,c and then concatenate them into one string before passing to function SaveToDebugInfoFile..

    void SaveToDebugInfoFile(char[] info)
    {
    ....
    }

    int main
    {
    int a =1;
    int b =2;
    int c =3;
    ....

    SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);
    }

    I hope to have in output something like this:
    "variable a=1 , variable b=2, variable c=3"


    int main
    {
    int a =1;
    int b =2;
    int c =3;
    ....

    SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);
    }

    I hope to have in output something like this:
    "variable a=1 , variable b=2, variable c=3"
    Andrej Viktorovich, Jun 29, 2012
    #9
  10. Andrej Viktorovich

    Stefan Ram Guest

    Andrej Viktorovich <> writes:
    >SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);


    Possibly, pass a format string and a va_list and then use vsnprintf.
    Stefan Ram, Jun 29, 2012
    #10
  11. Stefan pointed you the C way with vsnprintf. Since you seem to use C++ you
    should maybe ask also in a C++ newsgroup. There is a stringstream class. But
    I am not expirienced with that.
    Heinrich Wolf, Jun 29, 2012
    #11
  12. Andrej Viktorovich

    Mark Bluemel Guest

    On 29/06/2012 15:05, Andrej Viktorovich wrote:
    > Thank you, I got many answers to a lot of hypothetical questions.


    No - you got the answer to the question you asked. You were told why
    your example code failed and you were shown a number of ways in which,
    using C, your code could be made to work.

    > But how do you deal in case for example when you need just log some
    > variables like debug info.


    That is not the question you asked. The answer to it is probably
    language-specific. If you are actually planning to work in C, you'ld use
    a member of the printf family - your example below suggests that
    fprintf() may be appropriate.

    In C++ it is likely that there are other mechanisms which would be
    appropriate.

    If you are planning to use C++, you should post your questions to the
    appropriate newsgroup - comp.lang.c++

    >
    > void SaveToDebugInfoFile(char[] info)
    > {
    > ...
    > }
    >
    > int main
    > {
    > int a =1;
    > int b =2;
    > int c =3;
    > ...
    >
    > SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);
    > }
    >
    > I hope to have in output something like this:
    > "variable a=1 , variable b=2, variable c=3"
    >
    >
    > int main
    > {
    > int a =1;
    > int b =2;
    > int c =3;
    > ...
    >
    > SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);
    > }
    >
    > I hope to have in output something like this:
    > "variable a=1 , variable b=2, variable c=3"
    >
    Mark Bluemel, Jun 29, 2012
    #12
  13. בת×ריך ×™×•× ×©×™×©×™, 29 ביוני 2012 15:05:39 UTC+1, מ×ת Andrej Viktorovich:
    > Thank you, I got many answers to a lot of hypothetical questions.
    >
    > But how do you deal in case for example when you need just log some variables like debug info. How you construct string that will be saved to file? Do you really make such long and boring conversion to string routine (creating char[] variable, calling itoa ) for each variable of a,b,c and then concatenate them into one string before passing to function SaveToDebugInfoFile.
    >
    >

    No, you use vsprintf to construct

    SaveToDebugInfoFilef(char *format, ...)

    Then you just pass strings to this function, exactly as you would to printf().

    If you want to dump an array there's no way of doing it other than in a loop. You could write your own vsprintf() equivalent that takes arrays, but that would probably be more trouble than its worth.

    --
    Visit my website
    http://www.malcolmmclean.site11.com/www

    New halftoning routines
    Malcolm McLean, Jun 29, 2012
    #13
  14. Andrej Viktorovich <> writes:
    >> Assuming that C++ differs little from C in this respect, you're
    >> returning the address of a buffer which is local to the invocation of
    >> intToStr. It's not a good idea.

    >
    > I have feeling that in C i must create memory area and pass it like
    > parameter to function that converts int to string.
    >
    > But I would like to have simple function with one param of integer and
    > I would like to ask intToString to do all that job of creating memory
    > area and I need just char[] on utput. Is it possible to think that way
    > in C?


    Yes, but you have to think *really hard*. :cool:}

    You can't just return a string or array from a C function. It has to be
    allocated somewhere, and you pretty much have to manage that allocation
    yourself.

    There are (at least) three approaches:

    1. Declare the local buffer as "static", so its lifetime extends over
    the entire execution of the program. This has some drawbacks. There's
    only one buffer in memory, so successive calls will clobber the value
    from previous calls. And you have to decide how big the buffer needs to
    be.

    2. Have the caller pass in a pointer to (the first element of) its own
    buffer.

    3. Have the function allocate a new buffer using malloc(). This makes
    the caller responsible for free()ing the buffer when it's done with it.

    (Since you're using "cout << ...", you might consider using C++
    mechanisms for this, like std::string. But if you have any questions
    about C++, you'll need to ask in comp.lang.c++.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jun 29, 2012
    #14
  15. Andrej Viktorovich

    Fred K Guest

    On Friday, June 29, 2012 7:05:39 AM UTC-7, Andrej Viktorovich wrote:
    > Thank you, I got many answers to a lot of hypothetical questions.
    >
    > But how do you deal in case for example when you need just log some variables like debug info. How you construct string that will be saved to file? Do you really make such long and boring conversion to string routine (creating char[] variable, calling itoa ) for each variable of a,b,c and then concatenate them into one string before passing to function SaveToDebugInfoFile.
    >
    > void SaveToDebugInfoFile(char[] info)
    > {
    > ...
    > }
    >
    > int main
    > {
    > int a =1;
    > int b =2;
    > int c =3;
    > ...
    >
    > SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);
    > }
    >
    > I hope to have in output something like this:
    > "variable a=1 , variable b=2, variable c=3"
    >
    >
    > int main
    > {
    > int a =1;
    > int b =2;
    > int c =3;
    > ...
    >
    > SaveToDebugInfoFile(*/ need to pass a,b,c variables with some text /*);
    > }
    >
    > I hope to have in output something like this:
    > "variable a=1 , variable b=2, variable c=3"


    If all you want is to write it to a log file, what's wrong
    with just using fprintf() ? Then you don't ever need to
    create buffer space at all.
    Fred K, Jun 29, 2012
    #15
  16. Andrej Viktorovich

    Ike Naar Guest

    On 2012-06-29, James Kuyper <> wrote:
    > cout << 55 << "\n";
    >
    > It would also be more idiomatic to use endl rather than "\n".


    It's not the same thing. "\n" outputs a newline,
    std::endl output a newline and performs a flush.
    Ike Naar, Jul 1, 2012
    #16
  17. On Sun, 1 Jul 2012 21:26:20 +0000 (UTC), Ike Naar
    <> wrote:

    >On 2012-06-29, James Kuyper <> wrote:
    >> cout << 55 << "\n";
    >>
    >> It would also be more idiomatic to use endl rather than "\n".

    >
    >It's not the same thing. "\n" outputs a newline,
    >std::endl output a newline and performs a flush.


    This actually works in a C program???

    --
    Remove del for email
    Barry Schwarz, Jul 1, 2012
    #17
  18. Andrej Viktorovich

    Ike Naar Guest

    On 2012-07-01, Barry Schwarz <> wrote:
    > On Sun, 1 Jul 2012 21:26:20 +0000 (UTC), Ike Naar
    ><> wrote:
    >
    >>On 2012-06-29, James Kuyper <> wrote:
    >>> cout << 55 << "\n";
    >>>
    >>> It would also be more idiomatic to use endl rather than "\n".

    >>
    >>It's not the same thing. "\n" outputs a newline,
    >>std::endl output a newline and performs a flush.

    >
    > This actually works in a C program???


    Well, it works in the dialect called C/C++ :)
    Ike Naar, Jul 1, 2012
    #18
  19. Andrej Viktorovich

    James Kuyper Guest

    On 07/01/2012 05:31 PM, Barry Schwarz wrote:
    > On Sun, 1 Jul 2012 21:26:20 +0000 (UTC), Ike Naar
    > <> wrote:
    >
    >> On 2012-06-29, James Kuyper <> wrote:


    [Restored context:]
    >>> I thought you said you were using C? This looks like C++, a different,
    >>> though closely related language. You'll get better answers about such
    >>> things by going to comp.lang.c++. ... Also, do you realize
    >>> that you'd get a similar result by writing


    ....
    >>> cout << 55 << "\n";
    >>>
    >>> It would also be more idiomatic to use endl rather than "\n".

    >>
    >> It's not the same thing. "\n" outputs a newline,
    >> std::endl output a newline and performs a flush.

    >
    > This actually works in a C program???


    No, it was a comment referring to C++ code, as you can tell from the
    restored context quoted above.
    James Kuyper, Jul 1, 2012
    #19
  20. Andrej Viktorovich

    Ian Collins Guest

    On 07/ 2/12 10:22 AM, James Kuyper wrote:
    > On 07/01/2012 05:31 PM, Barry Schwarz wrote:
    >> On Sun, 1 Jul 2012 21:26:20 +0000 (UTC), Ike Naar
    >> <> wrote:
    >>
    >>> On 2012-06-29, James Kuyper<> wrote:

    >
    > [Restored context:]
    >>>> I thought you said you were using C? This looks like C++, a different,
    >>>> though closely related language. You'll get better answers about such
    >>>> things by going to comp.lang.c++. ... Also, do you realize
    >>>> that you'd get a similar result by writing

    >
    > ....
    >>>> cout<< 55<< "\n";
    >>>>
    >>>> It would also be more idiomatic to use endl rather than "\n".
    >>>
    >>> It's not the same thing. "\n" outputs a newline,
    >>> std::endl output a newline and performs a flush.

    >>
    >> This actually works in a C program???

    >
    > No, it was a comment referring to C++ code, as you can tell from the
    > restored context quoted above.


    Sense of humour MIA?

    --
    Ian Collins
    Ian Collins, Jul 1, 2012
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page