By Shuster


2019-08-13 19:05:39 8 Comments

I'm trying to write a program that reverses a name.

I'm using gets() to read the string, so it doesn't put the \n in the string.

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

void reverse_name(char *name)
{
    const char *p = name;
    char initial;

    while (*p == ' ')       // skip preceding white-spaces
        p++;

    initial = *p++;         // store letter of first name

    while (*p != ' ')       // skip until first white-space
        p++;                // between first and last name

    while (*p == ' ')       // skip additional white-spaces
        p++;                // p now points to the first letter of the last name

    strcpy(name, p);        // copy last name to the beginning
    strcat(name, ", ");
    strcat(name, &initial);
    strcat(name, ".");
}

For example, when inputting Immanuel Kant it should output Kant, I.. It prints garbage between the I and the . though. What's going wrong?

3 comments

@ForceBru 2019-08-13 19:11:29

strcat(name, &initial) tries to treat the data at &initial as a C string, which is NULL-terminated. It will continue copying data from this address until it finds the null byte. But &initial is a pointer to a byte on the stack, and there's no guarantee that *(&initial + 1) == 0, so it continues copying whatever data it finds on the stack into the string.

As pointed out in the comments, strcopying a part of a string into another part of the same string is undefined behavior. The memmove function is safer in this regard. However, you should probably just allocate a new memory region and build the resulting string there instead.

@chqrlie 2019-08-13 19:49:13

This is one of the problems, copying a string on itself has undefined behavior too.

@chqrlie 2019-08-13 19:23:35

There are multiple major problems in your code:

  • while (*p != ' ') p++; makes a bold assumption that the string contains at least one space after the first word. Calling reverse_name with the credentials of "Superman" or "Madonna", or just an empty string will cause undefined behavior.

  • strcpy(name, p); violates a constaint on the arguments of strcpy: copying between overlapping strings has undefined behavior.

  • strcat(name, &initial); passes the address of a single char, which is not a valid C string. You can append a single char with strncat(name, &initial, 1).

You just cannot simply perform the inversion in place as coded, and should be aware that the resulting string might be longer than the source string.

Here is an corrected version:

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

void reverse_name(char *name) {
    char *copy = strdup(name);

    char *first = copy + strspn(copy, " ");  // skip spaces before the first name
    int first_length = strcspn(first, " ");
    char *last = first + first_length + strspn(first + first_length);
    int last_length = strcspn(last, " ");

    if (last_length == 0) {
        /* no name or a single name */
        sprintf(name, "%.*s", first_length, first);
    } else {
        sprintf(name, "%.*s, %c.", last_length, last, *first);
    }
    free(copy);
}

@Shuster 2019-08-13 19:29:20

Regarding your first point: I should have clarified that one is assumed to ener a first and last name, so input like "Superman" is ignored here. Thanks for pointing out though!

@chqrlie 2019-08-13 19:45:58

@Shuster: defensive programming is a good idea, avoiding undefined behavior in unexpected situations.

@Bwebb 2019-08-13 19:19:24

Since you can assume the initial is always 1 char, use this instead of the failing strcat.

strncat(name, &initial, 1);

Related Questions

Sponsored Content

84 Answered Questions

[SOLVED] How do I make the first letter of a string uppercase in JavaScript?

4 Answered Questions

[SOLVED] C - [Error] invalid conversion from 'char' to 'const char*' [-fpermissive]

  • 2017-01-13 05:41:54
  • Tremmert
  • 14775 View
  • 1 Score
  • 4 Answer
  • Tags:   c

9 Answered Questions

[SOLVED] Difference between using character pointers and character arrays

1 Answered Questions

[SOLVED] Parsing a file in C (Lines)

8 Answered Questions

[SOLVED] C function to capitalize first letter of words in an array

4 Answered Questions

[SOLVED] Pick up upperCase letters from string and print them

  • 2014-01-21 16:27:20
  • Henry Lynx
  • 470 View
  • 0 Score
  • 4 Answer
  • Tags:   javascript string

1 Answered Questions

[SOLVED] Don't understand why C program crashes, pointer array of strings

2 Answered Questions

[SOLVED] concatenating/printing a string literal

  • 2009-04-14 04:15:52
  • Mitch Flax
  • 2136 View
  • 2 Score
  • 2 Answer
  • Tags:   c string

Sponsored Content