2

the function of my program is to simply have a char array with a first and last name, and switch it so it is last name first name. (Tom,Cruise --> Cruise,Tom). I have just started using pointers and cannot find a way to rearrange the Char array. I have tried for-loops and while loops but I don't really know how to tackle this problem. I don't necessarily need hard code. Even a suggestion would help get me moving in the right direction. I am not getting any errors. Due to requirements I am unable to modify the main function whatsoever and the function header has to be

char *LastFirstName(char *ptr).

Thanks

#include <iostream>
using namespace std;

char *LastFirstName(char *name);

int main()
{
  char name[41];
  char *ptr;
  // Force user to enter full name, if not entered, ask again
  while (true)
  {
    name[0] = '\0';
    cout << "Enter your full name: ";
    cin.getline(name, 40);
    if (name[0] == '\0')
        cout << "Name not entered. Re-enter full name.\n";
    else
        break;
  }
  cout << "Before calling function LastFirstName(), name is " << name 
  <<endl;

  ptr = LastFirstName(name);
  cout << "After calling function LastFirstName(), name is " << ptr << endl;

  system("pause");
  return 0;
}

// This is where I am havinbg trouble
char *LastFirstName(char *ptr) {
  char *p;
  p = ptr;
  int len = strlen(ptr);

  return ptr;
}
1
  • I guess you actually do not want to switch it inplace. Better go with a new char array and then afterwards return the pointer to the new array. So search for the last name, put it into your new array, then the first name and put it into the new array. Then return the pointer to the new array. Commented Oct 23, 2016 at 22:34

2 Answers 2

1

You can use this function:

void LastFirstName(char* first_last_name)
{
    char first_name[41] = {0};
    char last_name[41]  = {0};

    // Dunno what is your separator ' ' or ','...
    char* sep_index = strchr(first_last_name, ','); // This return the first index of ','.
    *sep_index = '\0';

    strcpy(first_name, first_last_name); // Lets copy first name.
    strcpy(last_name,  first_last_name + strlen(first_last_name) + 1); // Lets copy last name.

    // Lets copy it in reverse order.
    strcpy(first_last_name, last_name);
    strcpy(first_last_name + strlen(last_name) + 1, first_name);
    first_last_name[strlen(last_name)] = ',';
}

Notice that we don't need to return char* because the function is modifying the array it received as argument, so actually name array is now reversed as requested.

Sign up to request clarification or add additional context in comments.

5 Comments

What if I want to keep my header as is? Would there be any way to go about this instead? The "strcpy" looks very useful though I'll look into that and maybe I can come up with somthing.
Yes, just change my function from void to char* and return the same pointer you got as argument.
Currently I am getting an error. "strcpy" may be unsafe. So I use strcpy_s instead and it says "No instance of overloaded function strcpy_s matches the argument list.
I got rid of the CTR error but I am now getting "sep_index was null ptr"
Notice that strcpy may be unsafe if you don't know the size of the string you are copying from to the destination array. Because you might overflow the size you have allocated for it. It is not our case, we can tell for sure that our arrays are in the safe size ranges.
1
  1. ptr = LastFirstName(name); this doesn't really do anything. I mean, after that both ptr and name point to the same area in the memory... so it's pretty pointless (got it? 'pointless'... k, won't do that again.) to do that (the LastFirstName works on the memory pointed by name, which means that after the function ends name will hold the results.

  2. It would be easier to ask for the name, and then last name, then just swap the addresses that the pointers are pointing to... but that would be no-fun and we wouldn't learn anything from that, would we? (I'm just saying that there's another option. Don't get me wrong)

Now let's get to the coding. Since returning pointer in this case doesn't make sense (unless you want to have 2 arrays, each with different order), so let's change the function's declaration into void LastFirstName(char *ptr). Now we need to know where the name ends. We have to find the first occurence of a space (or any other character you want the two to be separated with), which is easily done with strchr(char*, int) function.

After that, since the name and last name doesn't need to be the same length we can't just swap their letters, it would be handy to just copy the name somewhere (another array), then override the name with the last name, copy the name right after that, and terminate with '\0'.

The code would look something like that (not tested, use with care):

void LastFirstName(char *ptr)
{
   char name[41], ptr2(ptr);
   const size_t nameLen(strchr(ptr, ' ')); // Change the space for whatever you want. btw, I used constructor here.
   strncpy(name, ptr, nameLen); // Copy the name from "ptr" to "name"
   ptr += nameLen+1; // Move pointer to the first character of the last name

   /* We could use some pre-made functions to avoid doing the for loop below
      but that's not the point in learning, is it? */
   for(size_t i(strlen(ptr) - nameLen - 1); i>0; --i) // I also used constructor here
   {
      *ptr2 = *ptr;
      ++ptr2;
      ++ptr;
   }

   *ptr2 = ' ' // Again, you can change it to whatever you want
   ++ptr2; // it's better to do it that way - compiles into faster code       

   strncpy(ptr2, name, nameLen); // let's copy the name back into our array
   ptr2 += nameLen; // Move the pointer to the end and append '\0'
   *ptr2 = '\0'; /* We would have passed nameLen+1 previously (and now)
   to get the null terminator copied within the strncpy, but it's better
   that way - it helps you to understand what happens behind the
   courtain. */

   return; // unnecessary, but it's a good habit imho
}
   /**
      Since you pass a copy of pointer, and not a pointer itself, to a function,
      you don't have to worry about getting it back to the position it was before.
   */

As you can see, I also made use of the strncpy(char*, char*, size_t) function.

Oh, and size_t is just a unsigned integer, used to express size in memory. It doesn't really differ from any other unsigned integer. It's just an alias.

And a little tip at the end: use C-style arrays (char array[]), wherever you can. Since their size is known at compile time the compiler can optimise it better. Not to mention that dynamic allocation (which I believe you will learn about next, that's what we use pointers for, mostly... left? I mean, right?) is just slower.

Hope I helped.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.