1

I am trying to get a full name from the user and display his name abbreviated, something like that :

“Edward Cantrell Cavender Davis” --> Name the user entered

"DAVIS, E. C. C.” -- Name abbreaviated

The problem is that I don't know how to do that, being new in C, I am thinking if there some library that does this, maybe.

The maximum size name that the user can enter is 200, and I need to check this through a function and display the name abbreviated.

My code : (I am stuck here)

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

void name_abbreviated (char name[200]) {

}

int main() {
    char name[200];
    printf("Type a full name : ");
    gets(name);
    name_abbreviated(name);
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Monteiro
  • 217
  • 5
  • 15
  • The first thing I would do is split the name string by the space character, so you would create 4 strings from `Edward Cantrell Cavender Davis`. Once you have split that string into sub-strings, just apply your logic based on order (i.e first sub-string needs to be abbreviated, last sub-string needs to be kept). You don't need a library to do this, as you are already using `` – 01010011 01000010 Jun 15 '17 at 14:32
  • Is what I thought, I am trying here to do this, if I get, I am going to post the code. Thanks for the help too. – Monteiro Jun 15 '17 at 14:35
  • 4
    Your question is too broad, you literally asking us to code for you. You have make a good question but your problem is not specific enough. – Stargateur Jun 15 '17 at 14:36
  • you really really really shouldn't use gets – StoryTeller - Unslander Monica Jun 15 '17 at 14:37
  • This might help you: https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c – 01010011 01000010 Jun 15 '17 at 14:38
  • Yeah I know that what I did with this code is pratically not too much for post some question, but is because I was without some ideas for how to do that, but thanks to the friend above, I now get some picture of how to do. Going to try here, and post the code later. – Monteiro Jun 15 '17 at 14:38
  • This sounds like one of the exercises for the [tag:cs50] course. You will probably find answers under that tag, or on [CS50 Stack Exchange](https://cs50.stackexchange.com). – Jonathan Leffler Jun 15 '17 at 14:54

3 Answers3

2

I am thinking if there some library that does this

No there isn't. You have to write your own code to achieve this.


An algorithm I could use is the following:

  1. Find the last whitespace (mark its index) and extract the last name.
  2. Loop over the name, until the white space (you have the index already). Every time you meet a space, store the initial letter of the word into a buffer.

Code:

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

#define LEN 200

void name_abbreviated (char name[]) {
    //printf("|%s|\n", name);
    char last_name[20];
    int j = 0, last_space_idx;
    for(int i = strlen(name) - 1; i >= 0; --i)
    {
        if(name[i] == ' ')
        {
            last_space_idx = i;
            while(name[i])
                last_name[j++] = name[++i];
            last_name[j] = '\0';
            break;
        }
    }
    //printf("|%s|\n", last_name);
    char rest_name[15];
    rest_name[0] = name[0];
    rest_name[1] = '.';
    rest_name[2] = ' ';
    j = 3;
    for(int i = 3; i < last_space_idx; ++i)
    {
        if(name[i] == ' ')
        {
            rest_name[j++] = name[i + 1];
            rest_name[j++] = '.';
            rest_name[j++] = ' ';
        }
    }
    rest_name[j - 1] = '\0';
    //printf("|%s|\n", rest_name);
    printf("%s, %s\n", last_name, rest_name);
}

int main() {
    char name[LEN];
    printf("Type a full name : ");
    fgets(name, LEN, stdin);
    printf("\n");
    name_abbreviated(name);
    return 0;
}

Output:

Type a full name : 
Davis, E. C. C.

Or, if you prefer see the Live demo.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    Thanks, it worked perfect. I am new to C, so this solution is a little complicated, would never thought in this one. I thought spliting all the strings and using other methods, but yours is better. Anyway, +1 and vote for best comment. – Monteiro Jun 15 '17 at 14:59
  • 1
    Minor: OP's `char name[200]; ... gets(name);` implies a `name` without the `'\n'`, so recommend `#define LEN `200+1)` and lop off any trailing `'\n'`. – chux - Reinstate Monica Jun 15 '17 at 17:50
  • Thanks for remindering this, I am going to change that in the code. – Monteiro Jun 15 '17 at 18:06
1

With the help of a data structure called linked list:

struct name {
    char string[200];
    struct name *next;
}

void name_abbreviated(char *input)
{
    struct name first;
    struct name *p = &first;
    struct name *last;

    int i = 0;
    while (sscanf(input, "%199s", p->string) != EOF) {
        i++;
        last = p; // keep pointer to possible last name

        input += strlen(p->string) + 1; // advance input, +1 for space

        p->next = malloc(sizeof(struct name));
        p = p->next;
    }

    // print last name
    printf("%s,", last->string);

    // print rest
    int j;
    p = &first;
    for (j = 0; j < i - 1; j++) {
        printf(" %c.", p->string[0]);
        p = p->next;
    }
    printf("\n");

    // free malloced memories
    struct name *prev = NULL;
    p = first.next;
    while (p) {
        prev = p;
        p = p->next;
        free(prev);
    }
}

int main()
{
    char name[200];
    printf("Type a full name: ");
    fgets(name, 200, stdin);
    name_abbreviated(name);
}
nglee
  • 1,913
  • 9
  • 32
1

I felt the answers here do not really leverage the C library much so I decided to show another way. If you're new to C, I really recommend going through the code and reading the man page (type man [command] in terminal and read the docs) for each of the functions here that you are not familiar with. Specifically, look at my use of sprintf() in the for loop. Understanding why that works is a huge step forward in C. I also recommend reading the seminal book The C Programming Language by Kernighan and Ritchie. You will not only only become a better C programmer, but a better programmer in general.

words is an array of strings where each string is a word in the name. In your example, the array would be:

words[0] = "Edward"
words[1] = "Cantrell"
words[2] = "Cavender"
words[3] = "Davis\n"

*note the new line character at the end of the last word. getline() returns the raw user input, and since user pressed enter to signify the end of input, the new line character carries through.

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

#define LEN 200

void name_abbreviated(char *name) {
    char tmp[LEN+1], abbr[LEN], *words[LEN], *token;
    int i = 0;

    strncpy(tmp, name, LEN);

    token = strtok(tmp, " ");
    while (token) {
        words[i++] = token;
        token = strtok(NULL, " ");
    }

    // remove '\n' from last word
    words[i-1][strlen(words[i-1]) - 1] = '\0'; 

    sprintf(abbr, "%s, ", words[i-1]);
    for (int j = 0; j < i - 1; j++) 
        sprintf(abbr + strlen(abbr), "%c. ", words[j][0]);

    puts(abbr);
}


int main(void) {
   char *name = NULL;
   char *abbr;
   size_t linecap = LEN;
   printf("Type a full name : ");
   getline(&name, &linecap, stdin);
   name_abbreviated(name);
}
g.o.a.t.
  • 420
  • 4
  • 13