Search code examples
cstringstructcharacterstrcat

Cannot add a specific character to the start of a char*, it only allows me to add it after in C?


I am having issues adding a '-' to the start of a string in C, as it causes a seg-fault. It seems to have no issue adding a '-' to the end of the string. Essentially there are two fields to the struct, and if one of the fields has a value of '-1', the value is meant to be negative, and a '-1' is to be added to the other field in the struct. Adding the 'ch' to the start is causing it to segfault.

Here is the code:

        unsigned int toPrint = size(unitLiterals);
    qsort(unitLiterals->element, toPrint, sizeof(Literal*), sort);
    for (unsigned int i = 0; i < toPrint; i++){
        Literal*literal = get(unitLiterals, i);
        if (literal->isNegative == 1){
            printf("%s", literal->name);

        }
        else {
            char *ch = "-";
            strcat((char*)literal->name, ch);
            printf("%s", literal->name);
        }
        if (i != toPrint-1){
            printf(" ");
        }
        else {
            printf("\n");
        }
    }

Struct initialization:

Literal *newLiteralStruct (char *name, int i){
    Literal *this = malloc(sizeof(Literal));
    this->name = name;
    this->isNegative = i; 
    return this;
}

Literal in Header file:

typedef struct Literal Literal;

struct Literal {
    char* name;
    int isNegative;
};

Solution

  • I would like the ch to be added at the start & not the end, and I don't know how to fix this.

    Don´t use strcat for this. strcat always appends a copy of the string pointed to by the second argument to the end of the string pointed to by the first argument, not the start of it.

    You can either Use a buffer and sequence of calls to strcpy instead:

     char *ch = '-';                          // Note the `-` is a character, not a string.
     char buf[N];                   
     buf[0] = *ch;                            // Copy `-` to the first element of `buf`. 
     strcpy(&buf[1], literal->name);          // Copy the string in `name` to `buf`,
                                              // starting at the second element of `buf`.   
     strcpy(literal->name, buf);              // Copy the string in `buf` back to `name`.
     printf("%s", literal->name);
    

    Note that name must have an extra element hold the added - character and of course an element to store the terminating null character. Also the buffer needs to be capable to hold the string in name plus the added - and the null character.

    You can also omit ch as it is not needed and make the code a little more compact:

     char buf[N];
     buf[0] = '-';
     strcpy(&buf[1], literal->name);
     strcpy(literal->name, buf);
     printf("%s", literal->name);
    

    Or you can sort each character of the string in name one element forward (including the null character) and then assign '-' to the first element of name:

    size_t len = strlen(literal->name);
    for ( size_t i = 0; i < (len + 1); i++ )
    {
        literal.name[i+1] = literal.name[i];
    }
    literal.name[0] = '-'; 
    

    But again here, name requires to be capable to hold the string + the '-' + the null character.