Everything below works the first time through, and the validation of the user's choice to proceed or not works, as does his choice to quit; but when it gets to cin.getline it just blows right through it without waiting for input. As my parents used to say, Where have I gone wrong?

//CIS 180 Rich Mansfield 0457321 11/20/09
//This program checks to see if an input is a palindrome

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<cctype>
using namespace std;

int main()
{
	const int MAX = 81;//Array size; no magic numbers; last char is null terminator
	char str[MAX];//Array to hold raw user input
	char proceed;//To allow user to choose to proceed or not, after initial run
	
	do //one time initially; user gets to choose to repeat or not at end
	{
	   // Get a line of input.
          cout	<< "Input a string of no more than "
	        	<< (MAX - 1) << " characters:\n";//saves last space for null terminator
	   cin.getline(str, MAX);//getline allows white space chars
	   //Doesn't pick up getline on second iteration
	   
	   // Display the input one character at a time.
   	int count = 0;// Loop counter variable
	   cout << "The sentence you entered is:\n";
	   while (str[count] != '\0')
	   {
	      cout << str[count];
	      count++;
	   }	//End while going through string
	
	int strlength;//var used to find pairs of characters to compare
	strlength = strlen(str);
	cout	<< endl	<< endl;
		
	//Convert all the characters in the string str to uppercase
	for(int i = 0; i < MAX; i++)
		if(str[i])//if there IS a character at that location
			str[i] = toupper(str[i]);//make sure it's uppercase (if already upper, no change)
	cout	<< str	<< endl	<< endl;
		
	//Remove all the special characters except letters a - z
	char str2[MAX];//Will need a new string to hold just the alpha dogs
	int j=0;//and a counter for its elements
	
	//str2 is declared to max out at 81, but I don't have to look at all of it
	for(int i = 0; i < strlength; i++)//strlength is all I need to look at
		if(isalpha(str[i]))//if the next character is a letter,
		{	
			str2[j] = str[i];//pass it into the new string
			j++;//increment j to go to next element in new string
		} 	//End of if isalpha
	str2[j]= '\0';//Put null terminator at end of new string
	cout	<< str2	<<	endl
		<< "strlength is "	<< strlength	<< endl
		<< "j is "			<< j
		<< endl	<< endl;
		
	int	back = j - 1;//back index points to the last character, drops the \0
	int	flag = 1;//start with true value for flag; set to break if it goes false
		
	//Compare the first character with the last character.
	//If they're are the same, compare the next characters.
	//front index is pointed to the first character in the string str2
	for(int front = 0; front <= j/2 ; front++)//j is the position of the \0 in str2
		//so j/2 is the midpoint that both back and front are converging on;
		//as long as front < j/2, it keeps incrementing.
	{
		if(str2[front] != str2[back - front])//comparing first element (0)
			//to last element (j - 1, or back, is last element, not counting \0
			//subtracting front el doesn't change that, at first, because 1st position is 0
			//but from then on, back decrements as fast as front increments
		{ 
			flag = 0;
			break;
		}  //End if string pairs not equal
	}	//End for loop comparing all pairs of characters
		
	
	if(flag == 0)
		cout	<< "It is not a palindrome"	<<endl;
	else
		cout<<"It's a palindrome"<<endl;
		
	//Re-initialize basic array in case user wants to do it again
	//Nope; doesn't work whether I have the next two lines, or not
	const int MAX = 81;//Array size; no magic numbers; last char is null terminator
	char str[MAX];//Array to hold raw user input
		
	//Does the user want to do it again? pg495
	cout	<< "One more time? (y/n) ";
	cin	>> proceed;

	//Validate response
	while (tolower (proceed) != 'y' && tolower(proceed) != 'n')
	{
		cout	<< "Please enter y or n: ";
		cin	>> proceed;
	}
    }	while (tolower(proceed) == 'y');//End do while
	
        return 0;
}	//End main fn

Recommended Answers

All 9 Replies

You really should comment your code.
And on a side note check out cin.ignore(); after cin>>'ing.

Ya when you use cin >> it leaves a '/n' in the buffer for some reason so you need to use cin.ignore() to get rid of that otherwise it will carry that over to your cin.getline() and will just use the '/n' making it do nothing like you say. BUT if you just stick cin.ignore() after your cin >>'s and when it asks you if you want to run one more time and you type something like "yes" then it will get rid of the 'e' and use the 's' in the buffer for your next word. Iono why it does that but to prevent it I would probably try creating a check to make sure the user only entered in 'y' or 'n' like 1 char not a string.

GL HF

commented: Very helpful +1

Thanks!

I take it that was an ironic comment!

I will go forth and cin no more

at least not without ignore.

It was sarcastic. There's no point in commenting every letter of code you write. It detracts from the readability, which is not the purpose of coding at all.

When only cin ing the cin.ignore(); isn't exactly important* ... but when you use getline(); it becomes important.

* not to say you should forget about it

I agree with twomers, using cin seems to be a 'safer' method than using getline(), in that cin will (unless something wack happens) will read in the entire input buffer while use of getline() will extract everything except the '\n'.. leaving it behind to thwart your subsequent attempts of reading the input stream:

istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );
Get line from stream

Extracts characters from the input sequence and stores them as a c-string into the array beginning at s.

Characters are extracted until either (n - 1) characters have been extracted or the delimiting character is found (which is delim if this parameter is specified, or '\n' otherwise). The extraction also stops if the end of file is reached in the input sequence or if an error occurs during the input operation.

If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it. If you don't want this character to be extracted, you can use member get instead.

The ending null character that signals the end of a c-string is automatically appended to s after the data extracted.

The number of characters read by this function can be obtained by calling to the member function gcount.

A global function with the same name exists in header <string>. This global function provides a similar behavior, but with standard C++ string objects instead of c-strings: see getline (string).

I have highlighted a few interesting points in the above documentation for getline(). First, highlighted in red, notice that it clearly states that (n-1) have been extracted from the input stream, so when using getline(), always be careful to account for this, either by adding a delimeter as a third argument (which will be discarded) or by use of ignore()which will extract and discard the '\n' that was left behind.

Secondly, I highlighed the use of get() which one should use if they do desire to leave characters behind. This function seems to have a wide variety of uses based on the number of arguments supplied to this function.

Also highlighted in green, "The number of characters read by this function can be obtained by calling to the member function gcount()." I never knew this, and would find this to be quite useful. I will definately try to incorporate this into future code... learn something new everyday.

In summary, I would like to state that cin is not the problem with your code, it is use of getline().. which isn't a bad thing (it definately has its benefits, especially when it comes to file I/O). Just remember to account for a trailing character that can be left behind after the first use of getline().

Thanks, Clinton - You've given me a lot to digest, but I'll take it a byte at a time. I also particularly like the gcount idea; I was wondering if there was a way to look at what's in the buffer, and that seems to be one way in.

Rich

No hurt feelings here - I put a lot of comments on for myself, but I'll erase all or most of them next time I post something.

This might be another way to read in a file without testing for eof()

do{
    
     getline(infile, file_string[i]);
     char_counter += gcount();
     i++;

while(gcount());

cout << i << " lines contained in file. ";
cout << char_counter << " characters read from file. ";
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.