-3

I have a simple function that will remove the spaces from a char array.

char removeSpaces(char input[])
{
    char output[128];
    int counter = 0; // the for loop will keep track of out position in "input", this will keep track of our position in "output"
    for (int n = 0; n < strlen(input); n++)
    {
        if (input[n] != ' ') // if a character is not a space
        {
            //add it too the new list
            output[counter] = input[n];
            counter++;
        }
        // if it is a space, do nothing
    }
    return output;
}

But when I run it it exits with code -1073741819 after the last iteration

Oskar
  • 119
  • 8
  • 1
    Read [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example), and [edit the question](https://stackoverflow.com/help/privileges/edit) to include one. Also, note that the return type of the function and the type of the returned value (`output`) are different. – kotatsuyaki Oct 24 '22 at 07:09
  • 3
    Does this answer your question? [Returning an array using C](https://stackoverflow.com/questions/11656532/returning-an-array-using-c) – Mathieu Oct 24 '22 at 07:10
  • 1
    You can't return a local array from your function – Mathieu Oct 24 '22 at 07:10
  • @Mathieu well, not without incurring undefined behavior anyway. – Chris Oct 25 '22 at 18:41

2 Answers2

0
  1. Your function should return a pointer to char not char
  2. But even if you change the function declaration, you can't return a reference to the local (automatic storage duration) object as this object stops existing when the function returns.
  3. Your code does not null character terminate the output string.

You can pass the buffer to the function, use malloc or change your variable to have a static storage duration (worst solution).

Examples:

char *removeSpaces(const char *str, char *buff)
{
    char *wrk = buff;
    while(*str)
    {
        if(*str != ' ')
        {
            *wrk++ = *str;
        }
        str++;
    }
    *wrk = 0;
    return buff;
}

char *removeSpaces1(const char *str)
{
    char *buff = malloc(strlen(str) + 1);
    char *wrk = buff;
    if(buff)
    {
        while(*str)
        {
            if(*str != ' ')
            {
                *wrk++ = *str;
            }
            str++;
        }
        *wrk = 0;
    }
    return buff;
}

char *removeSpaces2(const char *str)
{
    static char buff[1024];
    char *wrk = buff;
    while(*str)
    {
        if(*str != ' ')
        {
            *wrk++ = *str;
        }
        str++;
    }
    *wrk = 0;
    return buff;
}
Chris
  • 26,361
  • 5
  • 21
  • 42
0___________
  • 60,014
  • 4
  • 34
  • 74
  • _you can't return a reference to the local (automatic storage duration) object as this object stops existing when the function returns_ Maybe this should say you can't do this without venturing into the maddening realm of undefined behavior. – Chris Oct 25 '22 at 18:36
0

Returning the address of a "local block of storage" is always a bad idea. That memory is no longer yours to access once the function terminates.

Do you want to "remove spaces", or do you want to "make a copy without spaces"? Either way, it's not a good idea to have the "helper function" guess how much space might be needed for the copy. If the original is to be preserved, the caller should make a copy, then have the function "compact" the spaces out of the copy.

The following was written for another recent question. Notice that this version is able to remove all instances of several different characters in a single 'sweep' across the string.

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

// Define the function ahead of its use. It is its own prototype.
void remove_character( char *str, char *remove ) {
    // copy characters, but only increment destination for "non-remove" characters.
    for( size_t src = 0, dst = 0; ( str[dst] = str[src] ) != '\0'; src++ )
        dst += (strchr( remove, str[dst] ) == NULL);
}

int main( void ) {
    char s[] = "Thi!s is s!ome tex!t that we'!ll check for plagiarism";
    char symbols[] = "!s"; // Stripping out '!' and 's'

    puts( s ); // simpler
    remove_character( s, symbols );
    puts( s ); // simpler

    return 0;
}
Thi!s is s!ome tex!t that we'!ll check for plagiarism
Thi i ome text that we'll check for plagiarim

Replace the "!s" with " " and this would achieve your objective.

Fe2O3
  • 6,077
  • 2
  • 4
  • 20