简体   繁体   中英

C modify string using sprintf

Are the following steps all legal or may there be some undefined behavior?

#include <stdio.h>
#include <string.h>
#define MCAT(a) ((a)+strlen(a))

void test(char *ptr)
{
  static int i = 0;
  int n = 0;
  while ( n++ < 10 )
  sprintf( MCAT(ptr), " %d ", ++i );
  return;
}
int main()
{
   char buf[100];
   buf[0] = '\0'; //<- needed for MCAT macro
   test( buf );
   printf( "buf: %s\n\r", buf );

// also.. using pointer
   char *txt = buf;
   test( txt );
   printf( "txt: %s\n\r", txt );
// printf( "buf: %s\n\r", buf ); // same output, ok

}

In the "test" function, I have often seen strcpy with a temporary local variable, so I was wondering if you can also use sprintf to change the original string "buf".

It becomes undefined behavior once you write beyond the size of the buffer (here, 100 bytes), which is something that your test function doesn't check and cannot check, since it doesn't know the buffer size.

Thanks everyone for the replies.

Neglecting the overflow factor for a moment I was thinking that the most common strategies I've seen for using sprintf to concatenate strings are:

#include <string.h>
#include <stdio.h>
char * fixcpy(char *str); 

int main(int argc, char *argv[])
{
char buf[1000]; 
char *ptr = buf; 
buf[0] = '\0'; 

// "ptr +=" is added only for next usage  on case n.4

ptr += sprintf (buf + strlen(buf), "%s %d <- some data ...\n\r", "something", 1); 
printf( buf );

printf( "----------------------------------\n\r");

// or ... 
ptr += sprintf (&buf[strlen(buf)], "%s %d <- some data ...\n\r", "something", 2); 
printf( buf );

printf( "----------------------------------\n\r");

// or...
ptr += sprintf(strchr(buf, '\0'), "%s %d <- some data ...\n\r", "something", 3); 
printf( buf );

printf( "----------------------------------\n\r");

// or with pointers 
ptr += sprintf (ptr, "%s %d <- some data ...\n\r", "something", 4);
printf( buf );


// But if you want the output as argument of input you can't do that:
char tmp[1000];
strcpy( tmp, buf ); // because I want save the source  buf
printf( "---------ASPECTED ERROR-----------\n\r");
sprintf (tmp, "the output was:\n\r%s", tmp);
printf( tmp );

// But working on the other side?
printf( "---------------OK-----------------\n\r");
 sprintf (buf, "the output was:\n\r%s",   fixcpy(buf) );
 printf( buf );
 
// and probably work also...
 printf( "---------------OK?----------------\n\r");
 sprintf (buf, "the output was (new):\n\r%s%s",   fixcpy(buf),  fixcpy(buf) );
 printf( buf );

// 
}

char *fixcpy( char *str )
{
    static char buf[1000];
    strcpy( buf, str );
    return buf;
}

it looks pretty neat and clean to me if one knows the size of the data you're working on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM