last char of a string

Hi all, I have to make this program to check if a string is a palindrome, so I wanted to check if first and last char are the same, if second and second from last are equal etc. But it will not check the last char. I said str.length() - 1, because last char in string is '\n'. but it goes straight for second last char. so I said check for str.at(str.length()) but then it crashes...
anyway that's my code, please have a look and please help...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  cout << "\n\n\tEnter string to check if it is a polindrome: ";
getline (cin >> ws, str);

str.erase(remove_if(str.begin(), str.end(), ::isspace), str.end());

for (int i = 0; i <= str.length() - 1; i++)
    str.at(i) = toupper(str.at(i));

int c = 1;

for (int i = 0; i <= (str.length() - 2)/2; i++){
    correct = true;
    if (str.at(i) != str.at(str.length() - c))
        correct = false;
        c++;
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
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>

using namespace std;
int main()
{
   std::string new_str = "";
   std::string str = "RACSE CAR";
   
   str.erase(std::remove_if(str.begin(), str.end(), (int(*)(int))isspace), str.end());
   
   new_str.assign(str);
   std::reverse(str.begin(), str.end());

   if(new_str == str)
   {
	std::cout << "it is a palindrome" << std::endl;
   }
   else
   {
	std::cout << "it is not a palindrome" << std::endl;
   }

   std::cout << "reversed string " << new_str << std::endl;
   std::cout << "regular string " << str << std::endl;

   int x;
   cin >> x;
}
it's great, but I think my teacher expects me to use a loop and compare characters, any idea why its jumping over the last one or why it's crushing if I try to check for str.length()?
1) Bounds checking element access only adds unnesesary slowdown when used in situations where index is guaranteed to be in range (like iterating over a string). Prefer using debug libraries to check for developement errors.

2) *_or_equal operators are rarely used outside of math calculations. Canonical form of for loop uses < operator. In particular this: i <= str.length() - 1 will breaks hard on empty strings (causing access violations or out of range exceptions), when this: i <= (str.length() - 2)/2; will breaks on short strings and will not detect strings with differences in the middle.
Write simply: i < str.size(), i < str.size()/2.

3) Last character is s[s.size() - 1 /*- 0*/] and not str.at(str.length() - c /*← 0*/)

4) Think about using iterators to avoid calculations:
1
2
3
4
auto fi = s. begin(); //points to the first character
auto ri = s.rbegin(); //points to the last character
++fi; //Now fi points to the second char
++li; //Now li points to the second-to-last char 


5) Consider usage of standard algorithms:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

bool is_palindrome(std::string s)
{
    s.erase(std::remove_if(s.begin(), s.end(), [](char c){return !::isalpha(c);}),
            s.end());
    std::transform(s.begin(), s.end(), s.begin(), ::tolower);
    return std::equal(s.cbegin(), s.cbegin() + s.size()/2, s.crbegin());
}

int main()
{
    std::string s;
    std::getline(std::cin, s);
    std::cout << '"' << s << "\" is " << (is_palindrome(s)? "" : "not ") << "a palindrome\n";
}
if you want to use loops.

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
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>

using namespace std;
int main()
{
   char x[100];
   //std::string new_str = "";
   std::string str = "raSe car";
   
   str.erase(std::remove_if(str.begin(), str.end(), (int(*)(int))isspace), str.end());
   
   for (int i = 0; i <= str.length() - 1; i++)
    str.at(i) = toupper(str.at(i));

   int i;

   for( i=0; str[i]!='\0';++i);
   
    int k=0;

	for(int j=i-1; j >=0;--j)
	{
	  x[k] = str[j];
	  k++;
	}

	x[k] = 0;	
	
	string new_str(x);

	if(new_str == str)
   {
	std::cout << "it is a palindrome" << std::endl;
   }
   else
   {
	std::cout << "it is not a palindrome" << std::endl;
   }

   std::cout << "reversed string " << new_str << std::endl;
   std::cout << "regular string " << str << std::endl;
   

   int xx;
   cin >> xx;
}
Thanks to both of you, it was really helpful. I ended up using std::reverse even if I'm not supposed to (my teacher said there is no command to reverse string in c++!!!!! she's in for a surprise). The other things just wouldn't compile for me or I ended up with the same problem (couldn't check for last char or program crashed). Thank you again..
Topic archived. No new replies allowed.