By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,159 Members | 882 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,159 IT Pros & Developers. It's quick & easy.

sprintf() problem

P: 6
I encountered the problem as follows:
Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2.  
  3. char* fun(char* b)
  4. {
  5.   char* sTmp;
  6.   static char d[BUFSIZ];
  7.   bzero(d, BUFSIZ);
  8.   sprintf(d, "%s:%s", "Test", b);
  9.   sTmp = d;
  10.   return  sTmp;
  11. }
  12.  
  13. main()
  14. {
  15.   char a[100];
  16.   char b[100];
  17.   char tmp[100];
  18.   bzero(tmp, 100);
  19.   strcpy(a, "ABC123");
  20.   strcpy(b, "CDE456");
  21.   sprintf(tmp, "a: %s\n", fun(a));
  22.   printf("%s", tmp);
  23.   sprintf(tmp, "b: %s\n", fun(b));
  24.   printf("%s", tmp);
  25.   sprintf(tmp, "a: %s b: %s\n", fun(a), fun(b));
  26.   printf("%s", tmp);
  27. }
  28.  
/* 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
Mar 19 '07 #1
Share this Question
Share on Google+
11 Replies


Expert 100+
P: 1,510
your function fun() uses a static char d[] to hold the string so when you call
Expand|Select|Wrap|Line Numbers
  1.   sprintf(tmp, "a: %s b: %s\n", fun(a), fun(b));
  2.  
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
Mar 19 '07 #2

P: 6
Dear horace1

So how could I fix this problem? Please help.

Charles

your function fun() uses a static char d[] to hold the string so when you call
Expand|Select|Wrap|Line Numbers
  1.   sprintf(tmp, "a: %s b: %s\n", fun(a), fun(b));
  2.  
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
Mar 19 '07 #3

P: 6
Sorry for my mistake. There shouldn't be static keyword.

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

Please help. Thank you.
Mar 19 '07 #4

Expert 100+
P: 1,510
Dear horace1

So how could I fix this problem? Please help.

Charles
you could use malloc
http://www.cplusplus.com/malloc

to create a new array each time you call the function
Expand|Select|Wrap|Line Numbers
  1.   char* sTmp=malloc(BUFSIZ);
  2.  
however, remember to free() the allocated memory once you have finished with it
Mar 19 '07 #5

Expert 100+
P: 1,510
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.
Mar 19 '07 #6

P: 6
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
Mar 19 '07 #7

Expert 100+
P: 1,510
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
Mar 19 '07 #8

P: 51
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
Mar 19 '07 #9

P: 6
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

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
Mar 19 '07 #10

Expert 100+
P: 1,510
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.
Expand|Select|Wrap|Line Numbers
  1. char* fun(char* b)
  2. {
  3.   char* sTmp=malloc(BUFSIZ);
  4.   bzero(sTmp, BUFSIZ);
  5.   sprintf(sTmp, "%s:%s", "Test", b);
  6.   return  sTmp;
  7. }
  8.  
  9.  
Mar 19 '07 #11

P: 6
Horace1

Yes. It was what I did as you said.

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

Charles

I was assuming you do return a char * function result as in your original code, e.g.
Expand|Select|Wrap|Line Numbers
  1. char* fun(char* b)
  2. {
  3.   char* sTmp=malloc(BUFSIZ);
  4.   bzero(sTmp, BUFSIZ);
  5.   sprintf(sTmp, "%s:%s", "Test", b);
  6.   return  sTmp;
  7. }
  8.  
  9.  
Mar 19 '07 #12

Post your reply

Sign in to post your reply or Sign up for a free account.