a weird string prefix appears when strcat the str

Viewed 62

here is my code

#include <stdio.h>
#include <string.h>

int mypow(int s, int times); //only a pow function return a int

int main(void)
{
  int a;
  char str[80];
  char result[80];
  int cur;
  int input = 152;
  int len = 3;
  sprintf(str, "152 = ");
  strcat(result, str);
  for (a = 0; a < len; a++)
  {
    cur = input % 10;
    input = input / 10;
    if (a == 0)
    {
      sprintf(str, "%i", cur);
      strcat(result, str);
      sprintf(str, " + ");
      strcat(result, str);
    }
    else if (a < len - 1)
    {
      sprintf(str, "%i*%i", cur, mypow(10, a));
      strcat(result, str);
      sprintf(str, " + ");
      strcat(result, str);
    }
    else
    {
      sprintf(str, "%i*%i", cur, mypow(10, a));
      strcat(result, str);
    }
  }
  puts(result);
  return 0;
}

I hope to put the below code onto terminal

152 = 2 + 5*10 + 1*100

but I got such probably results

E:\c>e:\c\hello.exe
X152 = 2 + 5*10 + 1*100

E:\c>e:\c\hello.exe
X?52 = 2 + 5*10 + 1*100

E:\c>e:\c\hello.exe
X?52 = 2 + 5*10 + 1*100

what happened in this process

3 Answers

You use

sprintf(str, "152 = ");
strcat(result, str);

before you have initialized result.

Because result is not initialized, its contents is indeterminate (look at it as random or garbage).

To use strcat both strings needs to be proper null-terminated strings.

The easiest solution is to use strcpy to copy the literal string directly into result:

strcpy(result, "152 = ");

Or possibly skip that and initialize result at definition:

char result[80] = "152 = ";

The problem is in line

strcat(result, str);

You concatenate str to result, but you do not initialize result variable, so there is some garbage in there in the start.

You should use strcpy()

strcpy(result, str);

We all come here (SO) to learn and to grow.

Give this a try, then study how it functions.

You will REALLY benefit from learning/using standard library functions.

#include <stdio.h>

int main( void ) {
    char result[ 128 ]; // be generous!!
    int input = 152;
    int pos = sprintf( result, "%d = ", input ); // magic can happen

    for( int ind = 1; input; input /= 10, ind++ ) {
        char *join = " + ";
        if( input < 10 ) join = "";
        pos += sprintf( result + pos, "%i*%.*s%s", input % 10, ind, "10000000000", join );
    }

    puts( result );

    return 0;
}

The main 'trick' here is that sprintf() returns the number of characters it has written to the destination. By keeping track of those (accumulating), there's no need for intermediary buffers and lots of calls to "strcat/strcpy".

If you can write LESS code to do the job, you are making progress!

EDIT:

Inspired by positive recommendations from another, here is a version using a bit less code.

int main( void ) {
    char result[ 128 ], *at = result, *join = ""; // be generous!!
    int input = 152;

    at += sprintf( at, "%d = ", input ); // magic can happen
    for( int ind = 1; input; input /= 10, join = " + " )
        at += sprintf( at, "%s%i*%.*s", join, input % 10, ind++, "10000000000" );

    puts( result );

    return 0;
}

While the string of zeros is finite, the buffer size being written to is also very small... This is purely for fun...

And, for those with good eyes who prefer descending order:

int main( void ) {
    char str[128],*p=str,*join="",*pow="10000",*in="54321";
    int rev=strlen(in);
    
    p+=sprintf(p,"%s = ",in); // magic can happen
    while(*in)p+=sprintf(p,"%s%c*%.*s",join,*in++,rev--,pow),join=" + ";
    puts( str );

    return 0;
}

// Output:
54321 = 5*10000 + 4*1000 + 3*100 + 2*10 + 1*1

Finally, an counter example to show there is a massive cost to be paid for overdoing it... The following compiles and gives the desired output, but is (to most readers) impenetrable. Do NOT! write code like this except for your own amusement.

int main( void ) {
    char in[] = "123456", obuf[] = " + x*10000000";
    printf( "%s = ", in );
    int rev = strlen( in ) + 2;
    for( int o=3, i=0; (obuf[3] = in[i]) != '\0'; o=0, i++ )
        printf( "%.*s", rev+3-o-i-(in[i+1]?0:2), obuf+o );

    return 0;
}
/* Output
123456 = 1*100000 + 2*10000 + 3*1000 + 4*100 + 5*10 + 6
*/
Related