Removing Leading and Trailing whitespace

I am working on project and i am almost finished but the last part of the assignment is to take the user input and remove all leading and trailing white space, so that when i prompt the user for an answer, the input would match if they had spaces before or after their answer.

For Example if the correct answer is small fry: The user could enter:___small fry___ and it would match.
__ is representing spaces for this instance.
c++ has a lot of good stuff but someone dropped the ball on having a trim in algorithms. you will have to write it yourself.

do you want to eliminate, collapse, or ignore internal whitespace?
eg "x y" vs "x y" vs "xy" ?

leading trailing is easy. loop front to back, find the first non whitespace char in the string, and save its location. Loop back to front, find first non whitespace char and keep that location too. Take substring of the middle part, from the 2 saved locations inclusive. (this can be done in a single loop, of course, but its not generally going to be worth the trouble).
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>

std::string trim(const std::string& line)
{
    const char* WhiteSpace = " \t\v\r\n";
    std::size_t start = line.find_first_not_of(WhiteSpace);
    std::size_t end = line.find_last_not_of(WhiteSpace);
    return start == end ? std::string() : line.substr(start, end - start + 1);
}

int main()
{
    std::string line;
    std::getline(std::cin, line);
    std::string answer(trim(line));
    std::cout << '[' << answer << "]\n";
}

Simple and crude example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <limits> // for numeric_limits<>::max

int main()
{
   std::cout << "Enter some text: ";
   std::string input;

   std::cin >> std::ws >> input;

   std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

   std::cout << input << '\n';
}
Enter some text:      small fry     
small

Removes the leading whitespace before extracting the single word (small). The space between small and fry is itself whitespace.

The rest of the input in the stream's buffer is extracted and discarded.

There are ways to extract small and fry while extracting and discarding all the other whitespace characters, but that requires a bit more coding. One possible method:

1. Read the entire input line into a std::string

2. Create a std::stringstream from the string

3. Create an array (std::vector would be good for this use) to hold each individual token (small and fry are two such tokens)

4. Loop until the end of the stringstream's buffer is reached, extracting each token into a std::string while discarding any leading whitespace.

5. Insert the current extracted token into the array. Loop back to 4 until the the input's exhausted.

6. Done reading the entire line. You now have an array of the individual words/tokens the user entered. In your example it would be two elements of small and fry.
Alternatively, to "collapse" internal whitespace as well as ignore leading and trailing whitespace.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <sstream>
#include <string>

std::string getAnswer(std::istream& in)
{
    std::string line;
    std::getline(in, line);
    std::istringstream iss(line);
    std::string word;
    if (!(iss >> word))
        return std::string();
    std::string result(word);
    while (iss >> word)
    {
        result.push_back(' ');
        result += word;
    }
    return result;
}

int main()
{
    std::cout << "Enter answer: ";
    std::string answer(getAnswer(std::cin));
    std::cout << '[' << answer << "]\n";
}

You may also want to convert the characters to all upper or lower case.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <sstream>
#include <string>
#include <cctype>

std::string& lowercase(std::string& str)
{
    for (char& ch: str) ch = std::tolower(ch);
    return str;
}

std::string getAnswer(std::istream& in)
{
    std::string line;
    std::getline(in, line);
    std::istringstream iss(line);
    std::string word;
    if (!(iss >> word))
        return std::string();
    std::string result(lowercase(word));
    while (iss >> word)
    {
        result.push_back(' ');
        result += lowercase(word);
    }
    return result;
}

int main()
{
    std::cout << "Enter answer: ";
    std::string answer(getAnswer(std::cin));
    std::cout << '[' << answer << "]\n";
}

Last edited on
So i understand what you are saying to do but im not exactly sure how to implement what you put with my already existing code. Could you get me started? Basically what I need is for when i enter the text for "userinput" i need it to take whatever i type and remove all leading and trailing whitespace for two words but leave the space in the middle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>
#include <fstream>


using namespace std;

enum UserStatus { ANSWERING, INCORRECT, CORRECT };

/*
main - logic to read from file and prompt user for answer

return: status
*/
int main()
{
	UserStatus status;
	ifstream inputFile;
	string fName;
	string question;
	string answer;
	string junk;
	string userinput;

	cout << "File?" << " ";
	getline(cin, fName);
	inputFile.open(fName);

	getline(inputFile, junk);
	getline(inputFile, question);
	getline(inputFile, answer);

	int counter = 0;
	status = ANSWERING;

	while (status == ANSWERING)
	{
		cout << question << "? ";
		getline(cin, userinput);
		cout << endl;
		
		if (userinput == answer)
		{
			status = CORRECT;
		}
		else if (userinput != answer && counter == 2)
		{
			status = INCORRECT;
			counter++;
		}
		else if (userinput != answer && counter < 2)
		{
			status = ANSWERING;
			counter++;
			
		}

		switch (status)
		{
		case ANSWERING:
			cout << "Try Again" << endl;
			break;
		case CORRECT:
			cout << "Yay!" << endl;
			break;
		case INCORRECT:
			cout << "Sorry it's small fry" << endl;
			break;
		}
	}
Last edited on
Registered users can post here. Sign in or register to post.