sprintf() problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • karlc
    New Member
    • Mar 2007
    • 6

    sprintf() problem

    I encountered the problem as follows:
    Code:
    #include <stdio.h>
    
    char* fun(char* b)
    {
      char* sTmp;
      static char d[BUFSIZ];
      bzero(d, BUFSIZ);
      sprintf(d, "%s:%s", "Test", b);
      sTmp = d;
      return  sTmp;
    }
    
    main()
    {
      char a[100];
      char b[100];
      char tmp[100];
      bzero(tmp, 100);
      strcpy(a, "ABC123");
      strcpy(b, "CDE456");
      sprintf(tmp, "a: %s\n", fun(a));
      printf("%s", tmp);
      sprintf(tmp, "b: %s\n", fun(b));
      printf("%s", tmp);
      sprintf(tmp, "a: %s b: %s\n", fun(a), fun(b));
      printf("%s", tmp);
    }
    /* result */

    a: Test:ABC123
    b: Test:CDE456
    a: Test:CDE456 b: Test:CDE456

    The final printf returned "CDE456" twice instead of "ABC123" and "CDE456". Could you please help to resolve the problem?

    Thank you

    Karlc
    Last edited by horace1; Mar 19 '07, 09:26 AM. Reason: added code tags
  • horace1
    Recognized Expert Top Contributor
    • Nov 2006
    • 1510

    #2
    your function fun() uses a static char d[] to hold the string so when you call
    Code:
      sprintf(tmp, "a: %s b: %s\n", fun(a), fun(b));
    the result of the last fun(a) or fun(b) call is printed twice, i.e. if fun(a) is called first d[] holds "ABC123" when fun(b) is called this overwrites d[] with "CDE456" and hence "CDE456" is printed twice.

    note with using g++ I get
    a: Test:ABC123
    b: Test:CDE456
    a: Test:ABC123 b: Test:ABC123

    this is because the order of the evalution of the function parameters is not specified, i.e. fun(a)may be called by called before fun(b) or the other way around

    Comment

    • karlc
      New Member
      • Mar 2007
      • 6

      #3
      Dear horace1

      So how could I fix this problem? Please help.

      Charles

      Originally posted by horace1
      your function fun() uses a static char d[] to hold the string so when you call
      Code:
        sprintf(tmp, "a: %s b: %s\n", fun(a), fun(b));
      the result of the last fun(a) or fun(b) call is printed twice, i.e. if fun(a) is called first d[] holds "ABC123" when fun(b) is called this overwrites d[] with "CDE456" and hence "CDE456" is printed twice.

      note with using g++ I get
      a: Test:ABC123
      b: Test:CDE456
      a: Test:ABC123 b: Test:ABC123

      this is because the order of the evalution of the function parameters is not specified, i.e. fun(a)may be called by called before fun(b) or the other way around

      Comment

      • karlc
        New Member
        • Mar 2007
        • 6

        #4
        Sorry for my mistake. There shouldn't be static keyword.

        If fact, the problem still existed when I removed it.

        Please help. Thank you.

        Comment

        • horace1
          Recognized Expert Top Contributor
          • Nov 2006
          • 1510

          #5
          Originally posted by karlc
          Dear horace1

          So how could I fix this problem? Please help.

          Charles
          you could use malloc
          http://www.cplusplus.c om/malloc

          to create a new array each time you call the function
          Code:
            char* sTmp=malloc(BUFSIZ);
          however, remember to free() the allocated memory once you have finished with it

          Comment

          • horace1
            Recognized Expert Top Contributor
            • Nov 2006
            • 1510

            #6
            Originally posted by karlc
            Sorry for my mistake. There shouldn't be static keyword.

            If fact, the problem still existed when I removed it.

            Please help. Thank you.
            if you don't use static in this context the storage allocated to d[] is lost on exit from the function fun(). The progam MAY still appear to work but can cause segmentation errors when the memory is used for something else later on.

            Comment

            • karlc
              New Member
              • Mar 2007
              • 6

              #7
              Dear Horace1

              malloc() did solve the problem. It is what I expected. Thank you.

              However, as you reommended, how could I free() the memory if I need to return sTmp in the fun()? Could I free() the memory outside the fun()?

              Please help.

              Thank you

              Charles

              Comment

              • horace1
                Recognized Expert Top Contributor
                • Nov 2006
                • 1510

                #8
                Originally posted by karlc
                Dear Horace1

                malloc() did solve the problem. It is what I expected. Thank you.

                However, as you reommended, how could I free() the memory if I need to return sTmp in the fun()? Could I free() the memory outside the fun()?

                Please help.

                Thank you

                Charles
                yes, you just need the pointer

                Comment

                • chella
                  New Member
                  • Mar 2007
                  • 51

                  #9
                  Originally posted by karlc
                  Sorry for my mistake. There shouldn't be static keyword.

                  If fact, the problem still existed when I removed it.

                  Please help. Thank you.
                  Hi karlc,
                  Try executing this code. I hope u'll get the desired output.

                  #include <stdio.h>
                  #include<string .h>
                  void fun(char* b,char *str)
                  {
                  char d[100];
                  sprintf(d, "%s:%s", "Test", b);
                  strcpy(str,d);
                  }

                  int main()
                  {
                  char a[100];
                  char b[100];
                  char tmp[100];
                  char *str1,*str2;
                  str1=(char *)malloc(sizeof (char));
                  str2=(char *)malloc(sizeof (char));
                  strcpy(a, "ABC123");
                  strcpy(b, "CDE456");
                  fun(a,tmp);
                  printf("%s\n", tmp);
                  fun(b,tmp);
                  printf("%s\n", tmp);
                  fun(a,str1);
                  fun(b,str2);
                  sprintf(tmp, "a: %s b: %s\n", str1, str2);
                  printf("%s", tmp);
                  return 0;
                  }

                  Regards,
                  Chella

                  Comment

                  • karlc
                    New Member
                    • Mar 2007
                    • 6

                    #10
                    Dear Horace1

                    Glad to receive your reply again. You example worked well. Thank for your time.

                    However, I would like to keep return type of fun() be char*, because the function will be called by macro like:

                    #define MACRO1 fun("aaa")
                    #define MACRO2 fun("bbb")
                    ....

                    I though malloc() could help as you advised. The only problem was how to free the memory in the char* fun()

                    Shall I declare sTmp as global variable (it seemed not good to declare global variables ...). Do you have any other good suggestions?

                    BTW, Thank for your help

                    Karlc

                    Originally posted by chella
                    Hi karlc,
                    Try executing this code. I hope u'll get the desired output.

                    #include <stdio.h>
                    #include<string .h>
                    void fun(char* b,char *str)
                    {
                    char d[100];
                    sprintf(d, "%s:%s", "Test", b);
                    strcpy(str,d);
                    }

                    int main()
                    {
                    char a[100];
                    char b[100];
                    char tmp[100];
                    char *str1,*str2;
                    str1=(char *)malloc(sizeof (char));
                    str2=(char *)malloc(sizeof (char));
                    strcpy(a, "ABC123");
                    strcpy(b, "CDE456");
                    fun(a,tmp);
                    printf("%s\n", tmp);
                    fun(b,tmp);
                    printf("%s\n", tmp);
                    fun(a,str1);
                    fun(b,str2);
                    sprintf(tmp, "a: %s b: %s\n", str1, str2);
                    printf("%s", tmp);
                    return 0;
                    }

                    Regards,
                    Chella

                    Comment

                    • horace1
                      Recognized Expert Top Contributor
                      • Nov 2006
                      • 1510

                      #11
                      Originally posted by karlc
                      Dear Horace1

                      Glad to receive your reply again. You example worked well. Thank for your time.

                      However, I would like to keep return type of fun() be char*, because the function will be called by macro like:

                      #define MACRO1 fun("aaa")
                      #define MACRO2 fun("bbb")
                      ....

                      I though malloc() could help as you advised. The only problem was how to free the memory in the char* fun()

                      Shall I declare sTmp as global variable (it seemed not good to declare global variables ...). Do you have any other good suggestions?

                      BTW, Thank for your help

                      Karlc
                      I was assuming you do return a char * function result as in your original code, e.g.
                      Code:
                      char* fun(char* b)
                      {
                        char* sTmp=malloc(BUFSIZ);
                        bzero(sTmp, BUFSIZ);
                        sprintf(sTmp, "%s:%s", "Test", b);
                        return  sTmp;
                      }

                      Comment

                      • karlc
                        New Member
                        • Mar 2007
                        • 6

                        #12
                        Horace1

                        Yes. It was what I did as you said.

                        Is it OK not to call free() in the fun()?

                        Charles

                        Originally posted by horace1
                        I was assuming you do return a char * function result as in your original code, e.g.
                        Code:
                        char* fun(char* b)
                        {
                          char* sTmp=malloc(BUFSIZ);
                          bzero(sTmp, BUFSIZ);
                          sprintf(sTmp, "%s:%s", "Test", b);
                          return  sTmp;
                        }

                        Comment

                        Working...