-2

I have made this code such that whatever I type in a sentence has the first letter of the first word capitalized; While reducing any number of spaces in a sentence to just one space. However, my sentences are only reducing by one space. For example, if I put 3 spaces in a sentence, the output has spaces reduced by 1 to 2 spaces, but I want the output of words in a sentence to have only one space. I can't quite figure out what is wrong with my code and hence any help would be greatly appreciated. I have attached my code for reference below:

#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;

int main()
{
    int i = 0;              //i for counter
    string str;
    //String variable

    getline(cin, str);      //Get string from user
    int L = str.length();   //Find length of string
        //Display original string

    for (int i = 0; i < 100; i++)
    {
        str[i] = tolower(str[i]);
    }

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

    bool space;

    for (int j = i + 1; j < L; j++)
    {
        str[j] = str[j + 1];
        L--;
    }
    cout << str << endl;
    return 0;
}
Arun Kumar
  • 634
  • 2
  • 12
  • 26
  • The first problem is the out of bounds memory access in the first loop if the user types less than 100 characters. – melpomene Sep 29 '18 at 22:56
  • 1
    If your code is supposed to remove spaces ... why doesn't it look for space characters? – Swordfish Sep 29 '18 at 23:01
  • I tried the edit but it didn't output the required result. The spaces between the sentence actually increased and the second character in the first sentence actually got deleted. – faraz saleem Sep 29 '18 at 23:04
  • (Not related) Your include list is missing < string > for the definition of std::string. For portability, you should always include the headers for explicitly used classes. The next compiler, or even the next revision of your current compiler might not compile your code. – 2785528 Sep 29 '18 at 23:17
  • I am aware of these issues in the code but before fixing them I want to ensure that my base function of reducing any amount of spaces is properly executed. – faraz saleem Sep 29 '18 at 23:23
  • (not related) 100 is a magic number ... don't use them. Prefer the information trivially available from str functions. – 2785528 Sep 29 '18 at 23:24
  • The only reference to spaces in your code is `bool space`, which is never used. Please post the *actual* code. – Kevin Sep 29 '18 at 23:25
  • 1
    @farazsaleem It is better advised to fix those issues first usually, you never know which one of them are involved in your issue. – Rivasa Sep 29 '18 at 23:28
  • Consider handling multiple-spaces 'fix' separately from the capitalization 'fix' ... do 2 different functions. For 'easy' (but inefficient) spaces-fix, I would load the whole file into a single std::string, and 's.find' a double space, and fix the one found, then one at a time repeat until '.find' returns std::string::npos. – 2785528 Sep 29 '18 at 23:28
  • @farazsaleem Well, if you know something about `std::istringstream` and `std::accumulate`, this can be done with [very little need for loops](http://coliru.stacked-crooked.com/a/b10793ca4a28a169). Let the standard library do the work of separating the words, and then all you need to do is add in the space yourself. That example uses `accumulate`, but you could have done it yourself with a simple loop. – PaulMcKenzie Sep 29 '18 at 23:52
  • @farazsaleem If the example I linked to is too hard to understand, the easiest thing to do is rethink how this is done. Just separate the words into individual strings, then put the final string together by concatenating all the separate words, but put your own space in the middle. So what you really are doing is removing all the spaces first, and then putting back together the final string from the individual strings. That basically is what the example I linked to does, but it uses the standard library to do this work. – PaulMcKenzie Sep 30 '18 at 01:18

2 Answers2

0

Try this:

int main()
{
    std::string str;
    std::getline(cin, str);
    //Change case
    str[0] = toupper(str[0]);
    std::transform(str.begin() + 1, str.end(), str.begin() + 1, ptr_fun<int, int>(tolower));
    //Parsing time
    for (int i = 0; i <= str.size() - 1; i++) 
    {
        if (str[i] == ' ' && str[i + 1] == ' ') //if present & next are whitespaces, remove next
        {
                str.erase(str.begin() + i);
                i--; // rechecking condition
        }
    }
    std::cout << '\n' << str << '\n';
}

Output:

enter image description here

seccpur
  • 4,996
  • 2
  • 13
  • 21
0

Or doing it in a more modern way using iterators :

#include <iostream>
#include <cctype>

int main() {

  std::cout << "This is the string trimming function.\n" <<
  "Throw in a string and I will make sure all extra spaces " <<
  "will be reduced to single space.\n";

  std::string InputString, TrimmedString;
  int head = -1;
  int tail = -1;
  std::cout << "Please enter the input string :\n" << std::endl;
  std::getline(std::cin, InputString);

  for(std::string::iterator it = InputString.begin(); it <= InputString.end(); it++){
    if (*it != ' ' && head < 0 && tail < 0) {
      head = std::distance(InputString.begin(), it);
    }
    else if (head >= 0 && tail < 0 && (*it == ' ' || it == InputString.end())) {
      tail = std::distance(InputString.begin(), it);
      TrimmedString.append(InputString, head, (tail-head));
      TrimmedString.push_back(' ');
      head = -1;
      tail = -1;
    }
  }

  TrimmedString[0] = toupper(TrimmedString[0]);
  std::cout << "\nThe processed string is :\n\n" << TrimmedString << std::endl;
  return 0;
}
Arun Kumar
  • 634
  • 2
  • 12
  • 26