generated a String from 2 Strings

Viewed 106

I begin with my Code
I would like to add a function where the two names that are not identical are connected to a string. For this I would like to use my own function (stringlink that contains two strings as input parameters and generates a third string that contains the two strings connected by an & sign), but how I do this?

And yes I would like to compare two strings without the strcmp function.

Here is my Code:

#include <stdio.h>

int main () {
    char a[100];
    char b[100];
    int i;
    printf("please enter the first name:");
    scanf("%99s", a);
    printf("please enter the second name:");
    scanf("%99s", b);

    i=0;
    while(a[i] == b[i] && a[i]!='\0')
        i++;

    if ( a ==  b) {
        return 1;
    } else {
        return 0;
    }
    
    return 0;
}
3 Answers

If I understand you want to take two names, and only if they are not equal, joint them with a '&' character using a function, then one convenient option is to define your function to return a pointer to constant static array of characters of size length_a + length_b + 1 (the + 1 to account for the '&' character).

You can do that as follows, performing the comparison between a and b using a pointer to b and the index used copying a to the linked array, e.g.

#include <stdio.h>

#define MAXC 100        /* if you need a constant, #define one (or more) */
#define LINK '&'

const char *strlink (const char *a, const char *b, const char link)
{
    const char *p = b;                      /* pointer to be to compare with a */
    int i = 0, len = 2 * MAXC + 1;          /* index, max length for linked str */
    static char linked[2 * MAXC + 1];       /* static array for return */
    
    if (!a || !b)                           /* validate neither a || b NULL */
        return NULL;
    
    while (i < len-1 && *a && *a != '\n') { /* loop over chars in a */
        if (*a == *p)                       /* compare to chars in b */
            p++;
        linked[i++] = *a++;                 /* assign char from a to linked[index] */
    }
    
    if (p - b == i) {   /* if equal chars in b equal i, strings are the same */
        fputs ("error: string a & b are the same.\n", stderr);
        return NULL;
    }
    
    linked[i++] = link;                     /* add link between strings */
    
    while (i < len-1 && *b && *b != '\n')   /* loop b adding to linked */
        linked[i++] = *b++;
    
    linked[i] = 0;                          /* nul-terminate linked */
    
    return linked;
}

(note: there is no need to trim the '\n' included in the names filled by fgets() since the '\n' are taken as an end-of-string character in strlink())

Also note, since the array in strlink() is a static array, it will be overwritten the next time strlink() is called, so if you need to preserve each joined string, copy the successfully joined strings to permanent storage.

Then in main() you simply need to prompt for the two names and then validate the success or failure of strlink() by checking the return!. Only after you have validated the return do you print the linked string.

int main (void) {
    
    char a[MAXC], b[MAXC];
    const char *linked = NULL;
    
    fputs ("first name  : ", stdout);       /* take user-input with fgets() */
    if (!fgets (a, MAXC, stdin))            /* validate */
        return 0;
    
    fputs ("second name : ", stdout);       /* ditto */
    if (!fgets (b, MAXC, stdin))
        return 0;
    
    if ((linked = strlink (a, b, LINK)))    /* if linked successful, print */
        printf ("linked name : %s\n", linked);
}

Example Use/Output

$ ./bin/strlink
first name  : Mickey
second name : Minnie
linked name : Mickey&Minnie

If the names are the same:

$ ./bin/strlink
first name  : Mickey
second name : Mickey
error: string a & b are the same.

Or with whitespace:

$ ./bin/strlink
first name  : My dog
second name :  cat
linked name : My dog & cat

Returning int Instead of const char *

If you must have an int return instead of a character type, then making the change is straight forward. Per your comment the function returns 0 on success and 1 in the event the string are equal or in the event of failure. Modifications to the complete code are:

#include <stdio.h>

#define MAXC 100        /* if you need a constant, #define one (or more) */
#define LINK '&'

int strlink (char *linked, const char *a, const char *b, const char link)
{
    const char *p = b;                      /* pointer to be to compare with a */
    int i = 0, len = 2 * MAXC + 1;          /* index, max length for linked str */
    
    if (!a || !b)                           /* validate neither a || b NULL */
        return 1;
    
    while (i < len-1 && *a && *a != '\n') { /* loop over chars in a */
        if (*a == *p)                       /* compare to chars in b */
            p++;
        linked[i++] = *a++;                 /* assign char from a to linked[index] */
    }
    
    if (p - b == i) {   /* if equal chars in b equal i, strings are the same */
        fputs ("error: string a & b are the same.\n", stderr);
        return 1;
    }
    
    linked[i++] = link;                     /* add link between strings */
    
    while (i < len-1 && *b && *b != '\n')   /* loop b adding to linked */
        linked[i++] = *b++;
    
    linked[i] = 0;                          /* nul-terminate linked */
    
    return 0;
}

int main (void) {
    
    char a[MAXC], b[MAXC], linked[2 * MAXC + 1];
    
    fputs ("first name  : ", stdout);       /* take user-input with fgets() */
    if (!fgets (a, MAXC, stdin))            /* validate */
        return 0;
    
    fputs ("second name : ", stdout);       /* ditto */
    if (!fgets (b, MAXC, stdin))
        return 0;
    
    if (strlink (linked, a, b, LINK) == 0)  /* if linked successful, print */
        printf ("linked name : %s\n", linked);
}

(same output)


With Separate String Comparison Function

In the original strlink() function the check of whether a and b were equal strings was incorporated within the function. Per your comment, if that is needed as a separate function, the code can be rewritten as follows:

#include <stdio.h>

#define MAXC 100        /* if you need a constant, #define one (or more) */
#define LINK '&'

/** string compare without string.h */
int strcmp_nohdr (const char *a, const char *b)
{
    if (!a && !b) return 0;                 /* both NULL */
    if ( a && !b) return 1;                 /* valid a, but b NULL */
    if (!a &&  b) return -1;                /* valid b, but a NULL */

    for (; *a && *a == *b; a++, b++) {}     /* loop while chars the same */

    return (*a > *b) - (*a < *b);           /* -1 - a sorts before b,
                                             *  0 - strings are equal,
                                             *  1 - b sorts before a.
                                             */
}

int strlink (char *linked, const char *a, const char *b, const char link)
{
    int i = 0, len = 2 * MAXC + 1;          /* index, max length for linked str */
    
    if (!a || !b)                           /* validate neither a || b NULL */
        return 1;
    
    while (i < len-1 && *a && *a != '\n')   /* loop over chars in a */
        linked[i++] = *a++;                 /* assign char from a to linked[index] */
    
    linked[i++] = link;                     /* add link between strings */
    
    while (i < len-1 && *b && *b != '\n')   /* loop b adding to linked */
        linked[i++] = *b++;
    
    linked[i] = 0;                          /* nul-terminate linked */
    
    return 0;
}

int main (void) {
    
    char a[MAXC], b[MAXC], linked[2 * MAXC + 1];
    
    fputs ("first name  : ", stdout);       /* take user-input with fgets() */
    if (!fgets (a, MAXC, stdin))            /* validate */
        return 0;
    
    fputs ("second name : ", stdout);       /* ditto */
    if (!fgets (b, MAXC, stdin))
        return 0;
    
    if (strcmp_nohdr (a, b) == 0) {         /* check if a & b are equal */
        fputs ("error: string a & b are the same.\n", stderr);
        return 1;
    }
    
    if (strlink (linked, a, b, LINK) == 0)  /* if linked successful, print */
        printf ("linked name : %s\n", linked);
}

(same output)

The strcmp_nohdr() function behave exactly the same as strcmp() from string.h, but requires no header (.._nohdr).

Look things over and let me know if you have further questions.

You could use sprintf to create the third string.

char res[201];
sprintf(res, "%s&%s", a, b);
printf("%s\n",res);

Or even better, for creating the third string, you could take the length of a and b so that you don't waste space allocating it. Just rememember an additional space for & and \0 string terminator.

stringlink that contains two strings as input parameters and generates a third string that contains the two strings connected by an & sign), but how I do this?

It appears OP wants to avoid standard functions.

Create loops copying one character at atime.

char *stringlink(size_t size, char *dest, const char *a, const char *b) {
  char *d = dest;
  size_t i = 0;
  while (i + 1 < size && *a) {
    *d++ = *a++;
    i++;
  } 
  while (i + 1 < size && *b) {
    *d++ = *b++;
    i++;
  }
  if (i < size) {
    *d  = '\0';
  }
  return dest;
}
Related