why i always get "false" in my code - c++

I wrote code to check the input, I set the HavePunct flag always false. However when I input hello,world!! it returns the wrong results to me. Please let me know if you see any problems with my code:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string s,result_s;
char ch;
bool HavePunct = false;
int sLen = s.size();
cout << "Enter a string:" << endl;
getline(cin, s);
//检测字符串是否有符号
for (string::size_type i = 0;i != sLen; ++i) {
ch = s[i];
if (ispunct(ch)) {
HavePunct = true;
}
else
result_s += ch;
}
if (HavePunct) {
cout << "Result:" << result_s;
}
else {
cerr << "No punction in enter string!" << endl;
system("pause");
return -1;
}
system("pause");
return 0;
}

You are computing the length of the line before you enter any input. Hence, sLen is always zero. Move that line so it is after the line where you read the input.
cout << "Enter a string:" << endl;
getline(cin, s);
int sLen = s.size();

I cannot be sure, however it would seem because your iterator's upper bound is determined by the variable sLen, which you assign to be s.size() before you receive a string, therefore effectively making your upper bound 0 and causing your for loop never to execute.
Try this and let me know:
getline(cin, s);
int sLen = s.size();
for (string::size_type i = 0;i != sLen; ++i) {
ch = s[i];
if (ispunct(ch)) {
HavePunct = true;
}
else
result_s += ch;
}

Related

Stuck on removing whitespace from string without using any helper code c++

Create a program titled str_compress.cpp. This program will take a sentence input and remove all spaces from the sentence. (A good first step in encryption programs) Make sure that both the input and output strings are all stored in a single variable each. Do not use numbers or symbols. Include both upper-case and lower-case letters. Account for cases with multiple spaces anywhere.
This is what I have so far:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i = 0, j = 0, len;
string str;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
for (i = 0; i < len; i++)
{
if (str[i] == ' ')
{
for (j = i; j < len; j++)
{
str[j] = str[j + 1];
}
len--;
}
}
cout << str << endl;
system("pause");
return 0;
}
I can eliminate spaces, but only one at a time. If I copy and paste the for loop, I can remove all spaces for how many loops there are. I'm thinking that I can loop the for loop over and over until all spaces are gone, but I'm not sure how to do that. Also, I can't use anything like remove_all() or erase().
This is a strong clue for how the authors of your exercise want you to write your code:
Make sure that both the input and output strings are all stored in a single variable each
You should make a new string:
string new_str;
Use your loop over the input string. For each char in the string, check whether it is a space. If yes, do nothing. If no, append it to the output string:
for (i = ...)
{
char c = str[i];
if (c != ' ')
new_str.push_back(c);
}
Your loop's logic when removing a space is wrong. For instance, after removing a space, you then skip the next char in the string, which may be another space. Also, although you are decrementing the len, you don't resize the string to the new len before printing the new str value.
It should look more like this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
i = 0;
while (i < len)
{
if (str[i] == ' ')
{
for (j = i + 1; j < len; ++j)
{
str[j - 1] = str[j];
}
--len;
}
else
++i;
}
str.resize(len);
cout << str << endl;
/* or, if you are not allowed to use resize():
cout.write(str.c_str(), len);
cout << endl;
*/
/* or, if you are not allowed to use write():
if (len < str.length())
str[len] = '\0';
cout << str.c_str() << endl;
*/
system("pause");
return 0;
}
Live Demo
However, your instructions do say to "Make sure that both the input and output strings are all stored in a single variable each", which implies that separate std::string variables should be used for input and output, eg:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
str2 = str;
len = str2.length();
i = 0;
while (i < len)
{
if (str2[i] == ' ')
{
for (j = i + 1; j < len; ++j)
{
str2[j - 1] = str2[j];
}
--len;
}
else
++i;
}
str2.resize(len);
cout << str2 << endl;
/* or:
cout.write(str2.c_str(), len);
cout << endl;
*/
/* or:
if (len < str2.length())
str2[len] = '\0';
cout << str2.c_str() << endl;
*/
system("pause");
return 0;
}
Live Demo
Alternatively:
#include <iostream>
#include <string>
using namespace std;
int main()
{
size_t i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
str2.reserve(len);
for(i = 0; i < len; ++i)
{
char ch = str[i];
if (ch != ' ')
str2 += ch;
}
cout << str2 << endl;
system("pause");
return 0;
}
Live Demo
This is what worked for me. Thank you everyone for the help!!
int main()
{
int i, j, len;
string str, str2;
cout << "Enter string: ";
getline(cin, str);
len = str.length();
for (i = 0; i < len; ++i)
{
char ch = str[i];
if (ch != ' ')
str2 += ch;
}
cout << str2 << endl;
system("pause");
return 0;
}

isPalindrome not showing output and isPalindrome function is not tested with the string input as the string argument

#include <iostream>
#include <string.h>
using namespace std;
void convert(string& str) {
for (size_t i =0; i <str.length(); i++) {
str[i] = tolower(str[i]);
}
}
bool isPalindrome(string str) {
int length = str.length();
for (int i = 0; i < length / 2; i++) {
if (str[i] != str[length -1 -i]) {
cout << str << " is not a palindrome" << endl;
return false;
} else if (str[i] == str[length -1 -i] && toupper(str[i]) == toupper(str [length -1 -i])) {
cout << str << " is a palindrome" << endl;
} // for loop
return true;
}
return false;
}
int main () {
string str;
getline(cin, str);
convert(str);
isPalindrome(str);
return 0;
}
For some reason the output box in a homework grader for my coding assignment is showing blank but when I run my program it says whether or not it is Palindrome. Also the automatic grader also searches my code for a specific pattern like .+isPalindrome(\"Madam\").+ but the automatic grader says I only got 10 points because my code had a specific pattern of \s\isPalindrome(string str). I am really confused and do not know why my output is being shown blank and the automatic grader is looking for a specific pattern but I do not know what pattern???
You are just misunderstanding the output terminal. Everything is working fine just required to ask the user to enter a value.
#include <iostream>
#include <string.h>
using namespace std;
void convert(string& str) {
for (size_t i =0; i <str.length(); i++) {
str[i] = tolower(str[i]);
}
}
bool isPalindrome(string str) {
int length = str.length();
for (int i = 0; i < length / 2; i++) {
if (str[i] != str[length -1 -i]) {
cout << str << " is not a palindrome" << endl;
return false;
} else if (str[i] == str[length -1 -i] && toupper(str[i]) == toupper(str [length -1 -i])) {
cout << str << " is a palindrome" << endl;
} // for loop
return true;
}
return false;
}
int main () {
string str;
cout<<"Enter a string to check is it palindrome or not."<<endl;
getline(cin, str);
convert(str);
isPalindrome(str);
return 0;
}

s.erase is not working when trying to remove spaces from a string

I am trying to remove the spaces from a string to validate a Palindrome phrase. I have looked up other methods, but my professor literally copy and pasted the remove space for loop in our instructions but I can't get it to work and he says he doesn't want us going to the internet for help. I am trying to remove spaces from a phrase like "too hot to hoot" to validate it. I can get my program to work with single words like "bob", but not phrases.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char input[100];
cout << "Please enter a word/phrase: ";
cin >> input;
for (int i = 0; i < strlen(input); i++)
{
while (s[i] == ' ')//getting "s" is undefined error
s.erase(i,1);
}
int i = 0;
int j = strlen(input)-1;
bool a = true;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if(a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout<< input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}
Maybe you have not copy the result from temporary variable 's'. So, the modified codes should be:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <cstring>
using namespace std;
int main(int argc, char *argv[])
{
char input[100];
cout << "Please enter a word/phrase: ";
fgets(input, 100, stdin);
string s(input); // define a temporary variable 's'
int i = 0;
while (i < s.length())
{
if (s[i] == ' ' || s[i] == '\n')
{
s.erase(i, 1); // erase from variable 's', other then 'input'
continue;
}
i++;
}
// copy result from 's' to 'input'
sprintf(input, "%s", s.c_str());
int j = strlen(input) - 1;
bool a = true;
i = 0;
for (i = 0; i < j; i++)
{
if (input[i] != input[j])
{
a = false;
}
j--;
}
if (a)
{
cout << input << " is a Valid Palindrome." << endl;
}
else
{
cout << input << " is not a Valid Palindrome." << endl;
}
system("pause");
return 0;
}

C++ - does string contain a word - with simple loop?

//EDIT
the code below works only in case that str1 has only 1 beginning letter of str2; how to fix it?
for ex. if str1 / 2 = overflow / flo it works.
but if str1 is overflowfabc (has two "f"s) --> it doesn't work
//
I need to check for a word in a string using simple loop. The idea is:
find an element in str1 that is equal to 1. element of str2
if it exists, we set flag = 1, and it remains 1 if following elements are also equal. If they are not, flag is set to 0.
.
#include <iostream>
using namespace std;
int main() {
string str1, str2;
int flag;
cout << "Enter a string 1: ";
getline(cin, str1);
cout << "Enter a string 2: ";
getline(cin, str2);
for(int i = 0; i < str1.size(); i++)
{
if (str1[i] == str2[0]) // find element in str1 that is equal to first element of str2
{
flag = 1; //
for(int j = i+1; j < i + str2.size(); j++)
if (str1[j] != str2[j-i]) // checking if following elements are also equal
{
flag = 0; // if any of them is not equal
break;
}
if (flag==1)
cout << "str2 is Substring of str1" ;
else
cout << "str2 is NOT Substring" ;
}
}
return 0;
}
bool isSubStr(const string& parent, const string& child)
{
// Check each starting position
for (int i=0; i<(parent.size()-child.size()+1); ++i)
{
// Check if the substring starts at this position
// TODO make this a helper method to avoid the need for a flag
bool isSubString = true;
for (int j=0; j<child.size(); ++j)
{
if (parent[i + j] != child[j])
{
isSubString = false;
break;
}
}
if (isSubString)
{
return true;
}
}
return false;
}
The string class in C++ contains a function named find, and in my opinion you should use that.
The documentation can be found here.
An excerpt about the Return value:
The position of the first character of the first match.If no matches
were found, the function returns string::npos.
#include <iostream>
using namespace std;
int main() {
string str1, str2;
cout << "Enter a string 1: ";
getline(cin, str1);
cout << "Enter a string 2: ";
getline(cin, str2);
size_t found = str1.find(str2);
if (found != string::npos)
cout << "str2 is Substring of str1" << endl;
else
cout << "str2 is NOT Substring" << endl;
return 0;
}
It is shorter and easier to understand. So why not going with that ?
Otherwise I believe your code is not correct in more than one aspect; e.g.
you print out the text depending on the flag variable within the for loop. This does not look right to me.
the second for loop looks strange to me. I believe you are trying to program something that you believe might be considered sophisticated and well thought. To be honest with you, I suggest that do not try to do that. Do simple and clear.
Following your comment I took the time to try to improve your code.
#include <iostream>
using namespace std;
int main() {
string str1, str2;
int flag = 0;
cout << "Enter a string 1: ";
getline(cin, str1);
cout << "Enter a string 2: ";
getline(cin, str2);
for(unsigned int i = 0; i < str1.size(); i++) {
if (str1[i] == str2[0]) { // find element in str1 that is equal to first element of str2
unsigned int j = 0;
for( ; j < str2.size(); j++) {
if ( str1[i+j] != str2[j] ) { // checking if following elements are also equal
break;
}
}
if ( j == str2.size() ) { // if j equals the size of substring then all chars seem equal
flag = 1;
break;
}
}
}
if ( flag )
cout << "str2 is Substring of str1" ;
else
cout << "str2 is NOT Substring" ;
return 0;
}

Code can run but doesn't show the Result in Eclipse.?

Why the example code below can run fine on Visual Studio. In Eclipse, NetBean or CodeBlock the code can run but can't show the Result? Thanks All.
Ex: input one string.
a/ Uppercase first letter.
b/ Remove spaces inside the string.
#include "iostream"
#include "string.h"
using namespace std;
#define MAX 255
//uppercase first letter
char* Upper(char* input)
{
char* output = new char[MAX];
bool isSpace = false;
for (int i = 0; i < strlen(input); i++)
{
output[i] = input[i];
if (isSpace)
{
output[i] = toupper(output[i]);
isSpace = false;
}
if (output[i] == ' ') isSpace = true;
}
output[strlen(input)] = '\0'; // end of the string
output[0] = toupper(output[0]); // first character to upper
return output;
}
//remove space inside the string
char* RemoveSpaceInside(char* input)
{
char* output = new char[MAX];
strcpy(output, input);
int countWhiteSpace = 0;
for (int i = 0; i < strlen(output); i++)
{
if (output[i] == ' ')
{
for (int j = i; j < strlen(output) - 1; j++) // move before
{
output[j] = output[j + 1];
}
countWhiteSpace++;
}
}
output[strlen(output) - countWhiteSpace] = '\0'; // end of the string
return output;
}
int main()
{
char* name = new char[MAX];
cout << "Enter name: "; cin.getline(name, strlen(name));
cout << "Your name: " << name << endl;
cout << "\n******* Q.A *******\n";
char* qa = Format2VN(name);
cout << qa << endl;
cout << "\n******* Q.B *******\n";
char* qb = RemoveSpaceInside(name);
cout << qb << endl;
return 0;
}
char* name = new char[MAX];
cout << "Enter name: ";
cin.getline(name, strlen(name));
Calling strlen(name) will invoke undefined behavior, because you haven't initialized the array. Poor strlen will try to find the NUL character in an uninitialized byte mess. Definitely not a good idea.
What you probably want is:
cin.getline(name, MAX); // not sure if MAX or MAX-1 or whatever
In general, do yourself a favor and replace char* with std::string. Also, get a good C++ book.
Here is how your example would look like in actual C++:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>
std::string upper_first_letter(std::string s)
{
if (!s.empty()) s[0] = toupper(s[0]);
return s;
}
std::string remove_spaces(std::string s)
{
s.erase(std::remove_if(s.begin(), s.end(), isspace), s.end());
return s;
}
int main()
{
std::string name;
std::cout << "Enter name: ";
std::getline(std::cin, name);
std::cout << name << '\n';
std::cout << upper_first_letter(name) << '\n';
std::cout << remove_spaces(name) << '\n';
}