Whitespace causes another iteration of loop?

So, I am trying to request the user to input a string to the console. Then, I am trying to loop continuously (for now, anyways, until I debug this). However, whenever I enter a whitespace, it causes another iteration of the loop to begin. The more whitespaces I add, the more times the loop iterates when it was only supposed to iterate once after the console receives input once. What is wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "stdafx.h" // for Visual Studio Express 2013 for Windows Desktop
#include <iostream> // for cin and cout
#include <string> // for the input type

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	string input = "";
	while (true)
	{		
		//ask user for input
		cout << "Enter a string: \n";
		cin >> input;		

					
	}

return 0;
}
for string input use getline(), not std::cin which leaves the newline character in the input stream and trips on whitespace that may be present in a string
one way you could break out of a continous loop is to run a counter down to 0 from however many strings you need
btw int _tmain(int argc, _TCHAR* argv[]) - haven't seen this one before
Last edited on
btw int _tmain(int argc, _TCHAR* argv[]) - haven't seen this one before

It's a Windows extension for C++. IIRC it replaces _tmain with either main or wmain, and _TCHAR with char or wchar_t, depending on the local settings.

Even though std::getline is indeed prefered, you can get the whole line (not stopping at whitespaces) with std::noskipws.
std::cin >> std::noskipws >> str;
btw int _tmain(int argc, _TCHAR* argv[]) - haven't seen this one before
It is another variant of the function main() and is pretty popular in windows-specific coding.
int _tmain(int argc, _TCHAR* argv[]) and #include stdafx.h are what Visual Studio 2013 Express for Windows desktop uses as the main function. I think it's because I kept the box "precompiled header" checked.

Thank you for suggesting getline. That helped alot. I guess you just have to convert string input to a c style string first in order to use it, which is not too bad.
I guess you just have to convert string input to a c style string first in order to use it

or you could, if allowed, drop the c style string altogether and use std::string throughout. it's better because you can leverage all the standard library algorithms, iterators etc through std::string in that case
Do you know of a way to make getline work with strings? I would love to be able to use the algorithms to remove whitespace and such. I just get compiler errors if I try to pass a string into getline.
Here is my new code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <vector>

using namespace std;

int main()
{
	string input = "";
	while (true)
	{

		//ask user for input
		cout << "Enter regular expression, followed by enter twice: ";
		cin.getline(input, 1000);
		
	}
	return 0;
}


My compiler errors in Visual Studio Express 2013 for Windows Desktop are as follows:
Error 1 error C2664: 'std::basic_istream<char,std::char_traits<char>> &std::basic_istream<char,std::char_traits<char>>::getline(_Elem *,std::streamsize,_Elem)' : cannot convert argument 1 from 'std::string' to 'char *' c:\users\kevin\documents\visual studio 2013\projects\test\source.cpp 14 1 test
2 IntelliSense: no instance of overloaded function "std::basic_istream<_Elem, _Traits>::getline [with _Elem=char, _Traits=std::char_traits<char>]" matches the argument list
argument types are: (std::string, int)
object type is: std::istream c:\Users\Kevin\Documents\Visual Studio 2013\Projects\test\Source.cpp 14 6 test

Last edited on
The error says that istream::getline expects a buffer, not a std string.
Since you already specify the length you want (1000), you can do the following:
1
2
3
4
5
6
7
8
9
10
string input = "";
char buffer[1000];
	while (true)
	{

		//ask user for input
		cout << "Enter regular expression, followed by enter twice: ";
		cin.getline(buffer, sizeof buffer);
		input = std::string(buffer);
	}

But a better choice would be std::getline, where you don't need to specify a length and also much more simple.
1
2
3
4
5
6
7
8
9
string input = "";
	while (true)
	{

		//ask user for input
		cout << "Enter regular expression, followed by enter twice: ";
		std::getline(std::cin, input);
		
	}
Last edited on
Do you know of a way to make getline work with strings? I would love to be able to use the algorithms to remove whitespace and such
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
#include <algorithm>//std::remove_if
#include <cctype>//isspace
//http://www.cplusplus.com/reference/cctype/isspace/

int main()
{
    std::cout << "Enter your string \n";
    std::string input{};
    getline(std::cin, input);
    std::string input_copy{input};//save original string for later comparison
    input.erase(std::remove_if(input.begin(), input.end(), ::isspace), input.end());
    //remove_if shuffles the isspace characters to the end and the erase gets rid of them

    std::cout << "Original string: \n";
    std::cout << input_copy;
    std::cout << "\nRevised string without spaces: \n";
    std::cout << input << "\n";
}
Do you try to write a Shell prompt with this portion of code? your better choice could be use a do .. while iteration, this DO and after that ASK, is different to using while iteration. And of course if you want an iteraction with the cycle use get_line. Sorry for my english.
Ok. Thanks for the help, guys. I am attempting to put a 1000 character limit onto the string as well as a check to see if the word is empty so that it can exit the program if it is empty. I have debugged my code with a 1001 character string. It has correctly cut off the last character. However, the program thinks that the string's size is now 0 characters since the if statement below has evaluated to true, causing the program to terminate. Any thoughts why this could be?
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
#include <iostream>
#include <string>
#include <algorithm> // for removing whitespace

using namespace std;

int main()
{
	string input = "";
	char buffer[1001]; //1000 gave me problems

	while (true)
	{

		//ask user for input
		cout << "Enter regular expression: ";
		cin.getline(buffer, sizeof buffer);
		input = string(buffer);
                input.erase(remove_if(input.begin(), input.end(), isspace), input.end());
		
		if (input.size() == 0)
		{
			cout << "Program terminated";
			exit(0);
		}
	}
	return 0;
}
Last edited on
Oh, I'm sorry for that. I actually forgot about null-terminated strings.

Try printing the string before and after string::erase.

Also, string::erase deletes everything between the first parameter and the second, which are both iterators.

Searching the internet I found that std::remove_if removes elements from a range using a lambda. I never used it myself, but looking at http://www.cplusplus.com/reference/algorithm/remove_if/ seems like it returns an iterator to the first element after it's done, causing string::erase to delete the whole string. You should try using just remove_if. Hope it helps
Last edited on
Printing the string before and after erase showed that the method did most of what it should. The problem is if I try to exceed the buffer. If I do that, it messes up and the program terminates. It is just supposed to remove the additional characters and output the first 1000 characters while continuing as normal. If buffer's size is 1000, it messes up and exits starting at 1000 characters. Hopefully that makes sense. Here is the new code:
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
#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
	string input = "";
	char buffer[1000];

	while (true)
	{

		//ask user for input
		cout << "Enter regular expression: ";
		cin.getline(buffer, sizeof buffer);
		input = string(buffer);

		cout << "\n" << input << endl; // works fine if less than buffer
		input.erase(remove_if(input.begin(), input.end(), isspace), input.end());
		cout << "\n" << input << endl;
                
                // only supposed to run if input size is 0, but it instead runs if the buffer amount is exceeded
		if (input.size() == 0)
                {
			cout << "Program terminated";
			exit(0);
		}
	}
	return 0;
}

I only want the program to exit if the user puts in an empty line. How can I stop the program from exiting if the character size equals or exceeds the buffer?
Last edited on
If you want to limit to 1000 characters (in fact, bytes, considering unicode) you can get an arbitrary-length line and check if it's size is less than 1000, using getline from <string>.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string>
#include <iostream>

int main() {
    std::string buffer;
    while(true) {
        std::getline(std::cin, buffer);
        if (buffer.length() > 1000) {
             // Error
        }
        else {
            // Do whatever you want
        }
    }
}
Last edited on
Topic archived. No new replies allowed.