0

I am practicing my use of strcpy() in C and wrote this program.

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

int main(){


   int array[4] = {3,7,1,5};
   char str[4], temp[5];


   for (int i = 0; i < 4; i++){
       sprintf(&str[i],"%d", array[i]);
   }

   for (int i = 0; i < 4; i++){

       strcpy(&temp[i],&str[i]);
       printf("%c", temp[i]);
   }



     return 0;

}
~                

Unfortunately i get a 'stack smashing' error why is this ?

  • Try: `char str[4][10];`. You need multiple string buffers not a single one – kaylum Jun 21 '21 at 21:02
  • 2
    Have you gone straight to practicing it with an array before practicing it with a single string? Now you might have two unknowns to sort out instead of just one. – n. m. could be an AI Jun 21 '21 at 21:05
  • It's always best to include the **actual text** of an error that you're asking about. Specific errors have specific reasons, so stating exactly what error you're seeing helps us help you. – Caleb Jun 21 '21 at 21:42

2 Answers2

1

Strings in C must be terminated by a NUL byte ('\0'), and you must account for that when you size your buffers.

Given the contents of array, the following code

for (int i = 0; i < 4; i++) {
   sprintf(&str[i], "%d", array[i]);
}

will write bytes as follows, remembering that arrays are indexed from 0:

  • '3' to the 0th index, '\0' to the 1st index
  • '7' to the 1st index, '\0' to the 2nd index
  • '1' to the 2nd index, '\0' to the 3rd index
  • '5' to the 3rd index, '\0' to the 4th index

You write over the previously placed NUL with the current integer. Do you see the problem, though? There is not a 4th index in str[4]. You're going to write a byte to memory that you should not be accessing.


Even with str[5], so that there is room for the final NUL, the second part of your code would work in a very counter productive way.

The results of the first loop would have the contents of str be equal to "3714", such that

strcpy(&temp[i], &str[i]);

would then copy the strings as such:

  • "3714" to temp + 0
  • "714" to temp + 1
  • "14" to temp + 2
  • "4" to temp + 3

See how you're just walking along the same string, recopying the same tails to the same locations? printf("%c", temp[i]); is just going to print the first character of whichever tail you're on.

With enough room in str, this program is essentially a very round about way of writing:

int array[] = { 3, 7, 1, 5 };

for (int i = 0; i < 4; i++)
    printf("%d", array[i]);

Additionally, if array were to contain any integers whose representation as a string required more than a single byte (e.g., -5, 32), this code would not scale at all.


You'll want to change str to be a 2d array, containing space for all the strings you will create from the integers in array

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

int main(void) {
   int array[4] = {3, 7, 1, 5};
   char str[4][12], temp[12];

   for (int i = 0; i < 4; i++)
       sprintf(str[i], "%d", array[i]);

   for (int i = 0; i < 4; i++){
       strcpy(temp, str[i]);
       printf("[%d] %s\n", i, temp);
   }
}

though this is still not a very interesting exercise for the use of strcpy, seeing as we could just print str[i] directly.

Here's an example to play around with of using strcpy when searching for the last integer in an array whose string representation is longer than than two characters.

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

int main(void) {
    int array[] = { 3, 7, 123, 4, 13, -55, 29, 55 };

    char string[12] = "0", temp[12];

    for (int i = 0; i < (sizeof array / sizeof *array); i++)
        if (sprintf(temp, "%d", array[i]) > 2)
            strcpy(string, temp);

    printf("Final value: %s\n", string);
}
Oka
  • 23,367
  • 6
  • 42
  • 53
0

Each str[i] can only hold a single character, not a string - when you write

sprintf( &str[i], "%d", array[i] );

you are attempting to write a 2-character string1 to a 1-character buffer; the string terminator is "spilling" into the array element str[i+1] until you get to str[3], in which case the terminator spills over the end of the array.

To store an array of strings, you need to set aside a 2D array of char:

char str[4][N+1]; // can hold 4 strings of length N, +1 for the string terminator

Then in your sprintf statement, you'd write

sprintf( str[i], "%d", array[i] ); // no & operator on str[i]

  1. All the values in array are only one digit - for larger values, you would need more characters in your array. A string representation of a 32-bit int can have up to 10 digit characters, plus a sign character, plus the string terminator, so you need to set aside an array that can hold 12 elements, so ideally str should be declared as
    char str[4][12];
John Bode
  • 119,563
  • 19
  • 122
  • 198