Question

I cannot get my program to delete extra spaces that are found within the sentence, like if there is another space after a space. And the while loop I'm using to ask the user to continue is preventing the functions from running. When I remove it, the rest of the program runs.

This is the main function:

int main()
{
    bool program_start = 1;
    char user_sentence[MAX];

    cout<<"This program will take any sentence you write and correct any spacing\n"
        <<" or capitalization (not proper nouns) mistakes you have.\n";

    while(loop_continue(program_start))
    {
        input(user_sentence, MAX);
        uppercase_spacing(user_sentence);
        lowercase(user_sentence);
        cout<<user_sentence;
    }

    return 0;
}

My problem is with my uppercase_spacing function, I cannot get it to delete the extra spaces that are within the sentence.

Here are the void functions I'm using to edit the sentences:

void uppercase_spacing(char sentence[])
{
    int number = 0;
    if(isspace(sentence[0]))
    {
        for(int i = 0; i < MAX; i++)
        {
            sentence[i] = sentence[i + 1];
        }

        while(number<MAX)
        {
            if((isspace(sentence[number])) && (isspace(sentence[number+1])))
            {
                sentence[number] = sentence[number + 1];
            }
            number++;
        }

    sentence[0] = toupper(sentence[0]);

    }else{

        for(int index = 0; index<MAX;index++)
        {
            if((isspace(sentence[index])) && (isspace(sentence[index+1])))
                sentence[index]=sentence[index+1];
        }

        sentence[0] = toupper(sentence[0]);

    }
    return;
}

void lowercase(char sentence[])
{
    for(int i = 1; (i < MAX) && (i != '\0'); i++)
    {
        sentence[i] = tolower(sentence[i]);
    }

    return;
}

I use this boolean in all of my other programs, so I believe the problem is within the main part of the program.

Here is the boolean function I'm using for my while loop:

bool loop_continue(bool another_round)
{
    bool again = another_round;
    char continue_loop = 'y';
    cout<<"Would you like to continue? Type y or Y for yes,\n" 
        >>" or any other letter for no.\n";
    cin>> continue_loop;
    if((continue_loop == 'y' )||(continue_loop == 'Y'))
    {
        cout<<"Okay, let's do this!"<<endl;
        again = 1;
    }else
    {
        cout<<"Goodbye."<<endl;
        again = 0;
    }
    return again;
}

The input; the quotes are to stand in for the spaces.:

Candy CCandy " " " "something

The output; the spaces are still there:

Candy ccandy " " " "something

Was it helpful?

Solution

First, there are a number of off-by-one errors in your code. (The maximum index in char sentence[MAX] is MAX-1, and you have a number of cases where the loop body runs with index=MAX-1 and you access sentence[index+1]).

Second, let's dig into what your function is doing...

for(int index = 0; index<MAX;index++)
{
    // if sentence[index] and sentence[index+1] are both spaces....
    if((isspace(sentence[index])) && (isspace(sentence[index+1])))
        // set sentence[index] to sentence[index+1] (??!)
        sentence[index]=sentence[index+1];

    // now proceed to the next character
}

Do you see the problem now? You are setting a character known to be a space (sentence[index]), to a character known to be a space (sentence[index+1]). You are not actually removing any spaces.

OTHER TIPS

void compress_spaces( char *src)
{
    char *dst = src;

    // skip leading spaces first
    while( isspace( *src ))
        src ++;

    int space = 0;  // a character recently copied was a space

    for( ; *src; src++ )
        if( isspace( *src ))
        {
            if( !space )    // append a space only after a non-space char
                *dst++ = *src;
            space = 1;
        }
        else
        {
            *dst++ = *src;  // apped a non-space char always
            space = 0;
        }

    if( space )    // truncate the terminating space
        dst--;
    *dst = 0;      // terminate the resulting string
}

The reason nothing is happening is because you're just replacing a space with another space when you find two spaces in a row. The assignment you do doesn't actually shift the rest of the array, it just replaces the value at [number] with the value at [number+1]:

if((isspace(sentence[number])) && (isspace(sentence[number+1])))
{
    sentence[number] = sentence[number + 1];
}

When you find two spaces in a row like this, you'll need to enter an inner loop to find the first character that isn't a space, and then shift that character (and all subsequent characters) down to the original space.

The problem is that when you find a pair of spaces in the sentence, you just copy one over the other without removing anything, so you still have a pair of spaces. What you want is to copy everything after the extra space down to get rid of the space. Something like:

void uppercase_spacing(char sentence[]) {
    char *in, *out;

    in = out = sentence;
    while (*in) {  /* while there's more sentence... */
        while(isspace(*in)) in++;  /* skip any initial spaces */
        while (*in && !isspace(*in))  /* copy non-spaces */
            *out++ = toupper(*in++);   /* convert to upper case */
        *out++ = *in;  /* copy a single space or the end of the string */
    }
    if (--out > sentence && isspace(*--out))
        *out = 0;  /* trim off trailing space, if any */
}

Another issue you have is that you are shifting MAX characters even though there may be less.

For example, if MAX is 1500 and I enter the sentence "Help Me!", which is 9 characters (8 letters + 1 for nul terminator), your program will search 1500 characters.

I suggest you invest in some library functions such as:
std::strchr -- find a character in a C-string (such as a space).
std::memmove -- copies characters from one location to another, especially if the locations overlap.
std::strlen -- returns the number of characters in a string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top