-4

I'm working on the following homework problem:

Given the first name and last name as parameters, write the code of the function createFBlink(). The functions returns a facebook link which serves as an alternate email of the facebook user. The variable holding the facebook link should contain the minimum number of bytes required to store the string representing the facebook link. If there is no first name or last name, the function returns NULL.

For example, if firstname = tzuyu and lastname = chou, the facebook link is chou.tzuyu@facebook.com.

(See the original problem statement here.)

I've been trying to return a string from createFBlink into main. I've tried multiple methods such as turning char into static but I keep getting errors that I don't understand because I don't have a lot of experience with C.

I've had the best luck with using malloc, but I've come across a problem wherein if ever there are parameters to the function I'm sending from main, I end up with a crash after the input. Here's my code so far:

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

char *createFBlink(char *firstname , char *lastname) ;

int main(void)
{
    char firstname[24] , lastname[24], fblink[24] ;

    printf("Enter first name: ");
    scanf("%s", firstname);
    firstname[strlen(firstname)] = '\0';
    printf("\n Enter last name: ");
    scanf("%s", lastname);
    lastname[strlen(lastname)] = '\0';


    *fblink = createFBlink(firstname, lastname);
    if(*firstname == '\0'){
        printf("no facebook link generated");
    }else{
        printf("%s", *fblink);
    }
    getch();
    return 0;
}

char * createFBlink(char *firstname , char *lastname)
{
    int check1 = strlen(firstname) , check2 = strlen(lastname), num = check1+check2;
    char link = (char*) malloc(sizeof(char) * num);
    if(check1 == 0 || check2 == 0){
        *firstname = '\0' ;
    }else{

        strcat(*lastname, ".");
        strcat(*lastname, firstname);
        strcat(*lastname, "@facebook.com");
        strcpy(link , *lastname);
        return link;
    }
}
Jake
  • 1
  • 3
  • What is the crash? What line causes it? (Even if you don't understand it) – jeff carey Nov 18 '15 at 17:37
  • Enable warnings and try to re-compile. – this Nov 18 '15 at 17:40
  • If you wanna post the problem the least you could do is retype it here instead of posting a link to a picture of your teacher's powerpoint – Fabio Nov 18 '15 at 17:40
  • You, probably, did not understand what a pointer is. strcat, for instance, takes two pointers. – zdf Nov 18 '15 at 17:44
  • @jeffcarey a lot of the errors are saying that I'm making an integer from pointer without cast. The program runs and compiles but crashes after inputs. – Jake Nov 18 '15 at 18:00

2 Answers2

1
*link = (char *) malloc(24);

This is incorrect, it should be

link = (char *) malloc(24);

*link (the same as link[0]) is the first character of the string pointed by link, that assignment is just overwriting the character, not changing the pointer.

The following is also incorrect:

*fblink = createFBlink(firstname, lastname);

This:

strcat(*lastname, ...);

is incorrect in the same way. You are getting the first character of the string pointed by lastname, converting it to a pointer and passing this (obviously invalid) pointer to strcat. This is the most likely reason of the crash. Also, 24 characters may not be enough to hold the concatenated string.

Try to read a book about working with pointers in C, trying to understand them via trial-and-error is probably not the most effective way.

Paul
  • 13,042
  • 3
  • 41
  • 59
  • 1
    And `link = (char *) malloc(24)` is [technically correct, but poor style](http://stackoverflow.com/a/605858/824425). –  Nov 18 '15 at 17:43
  • @Rhymoid, yep, you are right, but it won't compile by C++ compiler without a cast, that was a "muscle memory" typing that cast. Not sure whether I need to edit the answer. – Paul Nov 18 '15 at 17:50
  • Hi! I do have a bit of knowledge when working with pointers but dynamic allocation is a really new topic for me. In fact a bit of the mistakes present in that code is because of the frustration and trial and error. One of the things I'm really having a hard time with is *fblink = createFBlink(firstname, lastname); I have no idea how that works and no previous answer had anything like that. – Jake Nov 18 '15 at 17:57
  • @Jake `createFBLink` returns `char*`. `fblink` is an array of `char`s that can be treated as a pointer to the first element of an array. `*fblink` is a first element of the array `fblink`. So when you do that assignment you assign `char*` to a `char`, which is incorrect. You either need to `strcpy(fblink, createFBLink(...))` to copy buffer returned by `createFBLink()` to `fblink` array or change definition of `fblink` to `char* fblink` and just assign a pointer `fblink = createFBLink(...)`. Also, you need to remember to free the pointer returned by `createFBLink()`. – Paul Nov 18 '15 at 19:16
  • @Jake Another better way to handle it is to change definition of `createFBLink` to accept output parameter: `void createFBlink(char *firstname , char *lastname, char* fblink)` and fill `fblink` inside of the function instead of allocating memory and returning a pointer to it. Then, in `main()` you call `createFBLink(firstname, lastname, fblink);`. Remember also, that 24 chars of `fblink` may not be enough to hold 24 chars of `firstname`, dot, 24 chars of `lastname` and 13 chars of "@facebook.com". – Paul Nov 18 '15 at 19:22
  • @Jake, Ok, I re-read the problem text, `createFBLink` should create a pointer to the link or `NULL`. Still you can accept output buffer as a parameter and either return pointer to it or `NULL` depending on the input parameters. – Paul Nov 18 '15 at 19:32
0

When working with strings, you need to understand the types you are using.

This is a fixed area in memory, of fixed size.

char buffer [24];

This is a dynamically allocated buffer that must be freed

char* szBuffer = malloc(24);
free(szBuffer)

Instead of doing that correctly, your createFBlink does malloc twice, and free zero times.

If you return a malloc'ed buffer from a function, you still must free it.

char * result = createFBlink(stuff);
free(result);

Since the types are different, you would need to use another function to move the string data from one to the other.

char * result = createFBlink(stuff);
strcpy(fblink, result, sizeof(fblink));
free(result);

And then you have additional risk from writing outside the allocated space. Let's try a made-up name with some common names.

firstname "Richard"
lastname  "Hernandez"
returned string "Hernandez.Richard@facebook.com" 

Oh look, 31 characters in a 24 character string. We just overwrite something, somewhere on your computer. Literally anything could happen, now.

So you have all kinds of risk. You have to match malloc with free. You have to keep track of the size. All of this is considered to be VERY BAD c++ style. The std::string class is highly recommended for this. You want your string class to take care of all the resource management, so you can't mess it up while you are using it.

std::string CreateFacebookLink (const std::string &firstname, const std::string &lastname){
    return firstname + "." + lastname + "@facebook.com";
}

std::string strFacebookLink (CreateFacebookLink("Richard", "Hernandez"));
Kenny Ostrom
  • 5,639
  • 2
  • 21
  • 30