Jump to: navigation, search

The C Programming Language, 2nd Edition, by Kernighan and Ritchie
Exercise 5.03 on page 107

Write a pointer version of the function strcat that we showed in Chapter 2: strcat(s,t) copies the string t to the end of s .



Solution by Richard Heathfield

/* ex 5-3, p107 */

#include <stdio.h>

void strcpy(char *s, char *t)
{
  while(*s++ = *t++);
}

void strcat(char *s, char *t)
{
  while(*s)
  {
    ++s;
  }
  strcpy(s, t);
}

int main(void)
{
  char testbuff[128];

  char *test[] =
  {
    "",
    "1",
    "12",
    "123",
    "1234"
  };

  size_t numtests = sizeof test / sizeof test[0];
  size_t thistest;
  size_t inner;

  for(thistest = 0; thistest < numtests; thistest++)
  {
    for(inner = 0; inner < numtests; inner++)
    {
      strcpy(testbuff, test[thistest]);
      strcat(testbuff, test[inner]);

      printf("[%s] + [%s] = [%s]\n", test[thistest], test[inner], testbuff);
    }
  }

  return 0;
}


Solution by Bryan Williams.

Give nineteen programmers a spec, and you'll get at least twenty completely different programs. As a tiny example of this, here's a totally different solution:

/*

  Exercise 5-3. Write a pointer version of the function strcat that we showed in 
                Chapter 2: strcat(s,t) copies the string t to the end of s.

  implementation from chapter 2:

/ * strcat:  concatenate t to end of s; s must be big enough * /
void strcat(char s[], char t[])
{
  int i, j;

  i = j = 0;
  while (s[i] != '\0')  / * find end of s * /
    i++;
  while ((s[i++] = t[j++]) != '\0')  / * copy t * /
    ;
}


  Author : Bryan Williams 

*/


/* strcat:  concatenate t to end of s; s must be big enough; pointer version */
void strcat(char *s, char *t)
{
  /* run through the destination string until we point at the terminating '\0' */ 
  while('\0' != *s)
  {
    ++s;
  }

  /* now copy until we run out of string to copy */
  while('\0' != (*s = *t))
  {
    ++s;
    ++t;
  }

}

#define DRIVER         6

#if DRIVER
#include <stdio.h>

int main(void)
{
  char S1[8192] = "String One";
  char S2[8192] = "String Two";


  printf("String one is (%s)\n", S1);
  printf("String two is (%s)\n", S2);
 
  strcat(S1, S2);
  printf("The combined string is (%s)\n", S1);

  return 0;
}

#endif



Solution by Jesus Alvarez (Category 0)

Nearly identical to the answer above, but compact.

( when s = "" it won't get the expected result, so check by yourself to figure out. --Added by Evan W.)

#include <stdio.h>

#define STR_BUFFER 10000

void strcat(char *, char *);

int main(int argc, char *argv[])
{
        char string1[STR_BUFFER] = "What A ";
        char string2[STR_BUFFER] = "Wonderful World!";

        printf ("String 1: %s\n", string1);

        strcat(string1, string2);

        printf ("String 2: %s\n", string2);
        printf ("Cat Result: %s\n", string1);

        return 0;
}

/* Concatenate t to s. */
void strcat(char *s, char *t)
{
        /*
         * '*++s' is used to reference the pointer before incremmenting it so
         * that the check for falsehood ('\0') is done with the next character
         * instead of '*s++' which would check, then increment. Using '*s++'
         * would increment the pointer to the base string past the null
         * termination character. When outputting the string, this made it
         * appear that no concatenation occurred because the base string is
         * cut off by the null termination character ('\0') that was never
         * copied over.
         */
        while(*++s); /* Get to the end of the string */
                      /*This statement is fine when s is not empty, and when s ="", it will not get the expected answer.*/
        while((*s++ = *t++));
}


Solution by Evan W

I think that Solution by Jesus Alvarez has a subtle blemish. When s = "", it won't get the expected result, cating the t string to a empty string s. Here follow my revision. Feel free to contact meEvan W.

#include <stdio.h>

#define STR_BUFFER 10000

void strcat(char *, char *);

int main(int argc, char *argv[])
{
        char string1[STR_BUFFER] = "What A ";
        char string2[STR_BUFFER] = "Wonderful World!";

        printf ("String 1: %s\n", string1);

        strcat(string1, string2);

        printf ("String 2: %s\n", string2);
        printf ("Cat Result: %s\n", string1);

        return 0;
}

/* Concatenate t to s. */
void strcat(char *s, char *t)
{
        /*
         * '*++s' is used to reference the pointer before incremmenting it so
         * that the check for falsehood ('\0') is done with the next character
         * instead of '*s++' which would check, then increment. Using '*s++'
         * would increment the pointer to the base string past the null
         * termination character. When outputting the string, this made it
         * appear that no concatenation occurred because the base string is
         * cut off by the null termination character ('\0') that was never
         * copied over.
         */
        while(*s++); /* Get to the end of the string */
        s--;           /*get back to the end of the string.*/
        while((*s++ = *t++));
}


Solution by menonsahab

// Nothing special here. Just replaces all s[i] in the original function with *(s+i)
void xstrcat(char *s, char *t)
{
	int i, j;
	i = j = 0;
	while(*(s+i) != '\0')
		i++;
	while((*(s+i+j) = *(t+j)) != '\0')
		j++;
}


Solution by Octavian

A short solution.

#include <stdio.h>
#define BUFFER 1000


void copy(char *, char *);

int main(void)
{
        char s[BUFFER] = "hello,";
        char t[BUFFER] = " world!";

        copy(s, t);

        printf("%s\n", s);
}

void copy(char *s, char *t)
{
        for (int i = 0; *s != '\0' && i <= BUFFER; i++, s++)
                ;

        for (int j = 0 ; *t != '\0' && j <= BUFFER; j++, t++, s++)
                *s = *t;
}


Solution by codybartfast (Category 0)

A slight variation on other answers:

void strcat(char *s, char *t)
{
	if (*s)
		while (*++s)
			;
	while ((*s++ = *t++))
		;
}


Solution by DtxdF

Try to imitate the real strcat, but it's a little long.

#include <stdio.h>
#include <stdlib.h>

char *my_strcat(char *s1, char *s2) {
	int c;
	int i;

	i = 0;
	while (*s1++)
		i++;

	s1--;

	while ((c = *s2++)) {
		*s1++ = c;
		i++;

	}

	return s1-i;

}

int main(void) {
	char str1[50] = "I love programming in ";
	char str2[] = "C";

	printf("%s\n", my_strcat(str1, str2)); /* I love programming in C */

	return EXIT_SUCCESS;

}

Solution by anonymous

Probably one of the simplest solutions here and it works when s == "" and t == "". Also, it is worth noting that this function is quite dangerous since it assumes s has enough space to fit t.

#include <stdio.h>

/*
    Exercise 5-3. Write a pointer version of the function strcat that we showed in Chapter 2: strcat (s, t) copies the string t to the end of s.
*/

void strcat(char *s, char *t);

int main()
{
    char a[1000] = "";
    char *b = " fox ";
    char c[] = "jumped over the ";

    printf("%s\n", a);
    strcat(a, ""); // works without issue
    printf("%s\n", a);
    strcat(a, "The quick brown");
    printf("%s\n", a);
    strcat(a, b);
    printf("%s\n", a);
    strcat(a, c);
    printf("%s\n", a);
    strcat(a, "lazy dog!");
    printf("%s\n", a);

    return 0;
}

// concatenate t to end of s; ASSUMES s is big enough
void strcat(char *s, char *t)
{
    for ( ; *s; s++) // move s to point to '\0' in str. Handles if s == "" (never increments), but does not work if s is uninitialized (e.g. char a[1000];) since its values are garbage
        ;
    while (*s++ = *t++) // copy t to s until t == '\0'. If t == "", the loop copies '\0' and terminates (since s is already pointed at '\0', there is no issue)
        ;
}
Personal tools