njava
asked on
Removing whitespace from inside the string
Here is my string:
A B(C) D
I wrote a trim function that removes leading and trailing whitespace.
After applying trim, I get a string like this:
A B(C) D
I have problems deleting whitespace (space and tabs) from that string afterwards.
The resulting string should be:
AB(C)D
string trim(string str)
{
char const* delims = " \t\r\n";
int pos;
// trim leading whitespace
string::size_type notwhite = str.find_first_not_of(deli ms);
str.erase(0,notwhite);
// trim trailing whitespace
notwhite = str.find_last_not_of(delim s);
str.erase(notwhite+1);
//delete whitespace inside the instruction
//----I need help here
while (str.find(" "))
{
pos = str.find(" ");
str=str.substr(pos);
}
//-------------trim is used in openFile function------
int openFile(string filename)
{
string line;
ifstream sin(filename.c_str(), ios::in);
if (!sin) {
cerr << "Can't open " << filename;
return 2;
}
while(getline(sin,line)){
//Calculate a number of lines
line_count++;
//remove whitespaces
line = trim(line);
//skip empty lines
if (line.empty())
continue;
cout << line << endl;
}
cout << "Number of lines: " << line_count << endl;
return 0;
}
A B(C) D
I wrote a trim function that removes leading and trailing whitespace.
After applying trim, I get a string like this:
A B(C) D
I have problems deleting whitespace (space and tabs) from that string afterwards.
The resulting string should be:
AB(C)D
string trim(string str)
{
char const* delims = " \t\r\n";
int pos;
// trim leading whitespace
string::size_type notwhite = str.find_first_not_of(deli
str.erase(0,notwhite);
// trim trailing whitespace
notwhite = str.find_last_not_of(delim
str.erase(notwhite+1);
//delete whitespace inside the instruction
//----I need help here
while (str.find(" "))
{
pos = str.find(" ");
str=str.substr(pos);
}
//-------------trim is used in openFile function------
int openFile(string filename)
{
string line;
ifstream sin(filename.c_str(), ios::in);
if (!sin) {
cerr << "Can't open " << filename;
return 2;
}
while(getline(sin,line)){
//Calculate a number of lines
line_count++;
//remove whitespaces
line = trim(line);
//skip empty lines
if (line.empty())
continue;
cout << line << endl;
}
cout << "Number of lines: " << line_count << endl;
return 0;
}
Here's another version:
void Trim(std::string& str, const std::string & ChrsToTrim = " \t\n\r", int TrimDir = 0)
{
size_t startIndex = str.find_first_not_of(Chrs ToTrim);
if (startIndex == std::string::npos){str.era se(); return;}
if (TrimDir < 2) str = str.substr(startIndex, str.size()-startIndex);
if (TrimDir!=1) str = str.substr(0, str.find_last_not_of(ChrsT oTrim) + 1);
}
inline void TrimRight(std::string& str, const std::string & ChrsToTrim = " \t\n\r")
{
Trim(str, ChrsToTrim, 2);
}
inline void TrimLeft(std::string& str, const std::string & ChrsToTrim = " \t\n\r")
{
Trim(str, ChrsToTrim, 1);
}
void Trim(std::string& str, const std::string & ChrsToTrim = " \t\n\r", int TrimDir = 0)
{
size_t startIndex = str.find_first_not_of(Chrs
if (startIndex == std::string::npos){str.era
if (TrimDir < 2) str = str.substr(startIndex, str.size()-startIndex);
if (TrimDir!=1) str = str.substr(0, str.find_last_not_of(ChrsT
}
inline void TrimRight(std::string& str, const std::string & ChrsToTrim = " \t\n\r")
{
Trim(str, ChrsToTrim, 2);
}
inline void TrimLeft(std::string& str, const std::string & ChrsToTrim = " \t\n\r")
{
Trim(str, ChrsToTrim, 1);
}
ASKER
Axter:
How to invoke these functions in main() in your second example?
In the first example, your trim function doesn't remove space from inside the string. That's what I am trying to accomplish.
How to invoke these functions in main() in your second example?
In the first example, your trim function doesn't remove space from inside the string. That's what I am trying to accomplish.
Or that:
string removeWhitespace(const string& str)
{
string s;
for (int i = 0; i < str.length(); ++i)
if ((unsigned char)str[i] >= (unsigned char)' ')
s += str[i];
return s;
}
Regards, Alex
string removeWhitespace(const string& str)
{
string s;
for (int i = 0; i < str.length(); ++i)
if ((unsigned char)str[i] >= (unsigned char)' ')
s += str[i];
return s;
}
Regards, Alex
Correction:
if ((unsigned char)str[i] > (unsigned char)' ')
if ((unsigned char)str[i] > (unsigned char)' ')
ASKER
it should be
if ((unsigned char)str[i] > (unsigned char)" ")
if ((unsigned char)str[i] > (unsigned char)" ")
ASKER
itsmeandnobodyelse:
when I use your removeWhitespace function inside the while loop, I get empty lines in the output.
while(getline(sin,line)){
//Calculate a number of lines
line_count++;
//remove whitespaces
line = trim(line);
//skip empty lines
if (line.empty())
continue;
line=removeWhitespace(line );
cout << line << endl;
}
when I use your removeWhitespace function inside the while loop, I get empty lines in the output.
while(getline(sin,line)){
//Calculate a number of lines
line_count++;
//remove whitespaces
line = trim(line);
//skip empty lines
if (line.empty())
continue;
line=removeWhitespace(line
cout << line << endl;
}
That works ok here:
string removeWhitespace(const string& str)
{
string s;
for (int i = 0; i < str.length(); ++i)
if ((unsigned char)str[i] > (unsigned char)' ')
s += str[i];
return s;
}
int main() {
string s = " A B ( C) D ";
s = removeWhitespace(s);
cout << s << endl;
return 0;
}
string removeWhitespace(const string& str)
{
string s;
for (int i = 0; i < str.length(); ++i)
if ((unsigned char)str[i] > (unsigned char)' ')
s += str[i];
return s;
}
int main() {
string s = " A B ( C) D ";
s = removeWhitespace(s);
cout << s << endl;
return 0;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you, guitaristx !
>> when I use your removeWhitespace function inside the while loop, I get empty lines in the output.
In your code sample, you used trim() function *and* removeWhitespace(), so I cannot say what happened.
Regards, Alex
In your code sample, you used trim() function *and* removeWhitespace(), so I cannot say what happened.
Regards, Alex
ASKER
Hi Alex,
I tried different combinations: only with trim, only with removeWhitespace and both.
Every time I used removeWhitespace it would produce empty strings.
What was more surprising is that when in removeWhitespace I set a condition not equal space, it printed to the screen my string unchaged char by char. So, this function somehow failed to recognize the space.
if ((unsigned char)str[i] != (unsigned char)" ")
However, removeWhitespace worked on a single string, in main(), with double quotes for the space. But when I changed double quotes to single quotes it didn't work.
Anyway, guitaristx's solution worked like a charm and saved me from mental exhaustion :) This problem seemed to be so easy in the beginning...
I tried different combinations: only with trim, only with removeWhitespace and both.
Every time I used removeWhitespace it would produce empty strings.
What was more surprising is that when in removeWhitespace I set a condition not equal space, it printed to the screen my string unchaged char by char. So, this function somehow failed to recognize the space.
if ((unsigned char)str[i] != (unsigned char)" ")
However, removeWhitespace worked on a single string, in main(), with double quotes for the space. But when I changed double quotes to single quotes it didn't work.
Anyway, guitaristx's solution worked like a charm and saved me from mental exhaustion :) This problem seemed to be so easy in the beginning...
>> if ((unsigned char)str[i] != (unsigned char)" ")
This doesn't work because you're typecasting a const char* as an unsigned char, which will more than likely do pointer truncation, and you'll have no freakin' idea what value it's going to use. Try this:
if (str[i] != ' ')//notice the single quote rather than the double quote
This doesn't work because you're typecasting a const char* as an unsigned char, which will more than likely do pointer truncation, and you'll have no freakin' idea what value it's going to use. Try this:
if (str[i] != ' ')//notice the single quote rather than the double quote
ASKER
itsmeandnobodyelse:
Sorry for the mishap. I just tried guitaristx's suggestion in the last comment. Your solution also works. I made a mistake with double quotes.
Sorry for the mishap. I just tried guitaristx's suggestion in the last comment. Your solution also works. I made a mistake with double quotes.
ASKER
itsmeandnobodyelse:
I can give you 50 points but I don't know how. I already accepted the answer.
I can give you 50 points but I don't know how. I already accepted the answer.
Hi, njava
Thanks that you tested my solution again. It was less frustrating getting no points than being mistakenly judged.
>> I can give you 50 points but I don't know how
If you would like to give additional points, you could open a new question titled 'points for ...', and accept an appropriate answer to that.
Regards, Alex
Thanks that you tested my solution again. It was less frustrating getting no points than being mistakenly judged.
>> I can give you 50 points but I don't know how
If you would like to give additional points, you could open a new question titled 'points for ...', and accept an appropriate answer to that.
Regards, Alex
ASKER
Alex:
here is the link to your 50 points
https://www.experts-exchange.com/questions/21282983/Points-for-itsmeandnobodyelse.html
here is the link to your 50 points
https://www.experts-exchange.com/questions/21282983/Points-for-itsmeandnobodyelse.html
Can you use strtok....
char *s1, *s2;
s1 = strtok(str," ");
while( (s2 = strtok(NULL," ")) != NULL)
{
strcat(s1,s2);
memset(s2,0,strlen(s2));
}
Soemthing like this... This will remove all spcases before, in the middle and also trailing the string...
Of course the above need to have some error checks....
char *s1, *s2;
s1 = strtok(str," ");
while( (s2 = strtok(NULL," ")) != NULL)
{
strcat(s1,s2);
memset(s2,0,strlen(s2));
}
Soemthing like this... This will remove all spcases before, in the middle and also trailing the string...
Of course the above need to have some error checks....
static bool
strip(const char c)
{return (c == ' ' || c == '\t');}
//...
std::string s ("whatever");
//...
s.erase(std::remove_if(s.b egin(),s.e nd(),strip ),s.end()) ;
strip(const char c)
{return (c == ' ' || c == '\t');}
//...
std::string s ("whatever");
//...
s.erase(std::remove_if(s.b
Your doing it the hard way. The following two lines will
remove the spaces from everywhere.
#include <algorithm>
string::iterator junkI = remove(str.begin(),str.end (),' ');
str.erase(junkI,str.end()) ; // Make sure you remove the junk left at the end of the string
remove the spaces from everywhere.
#include <algorithm>
string::iterator junkI = remove(str.begin(),str.end
str.erase(junkI,str.end())
Sorry I didn't see swap-dog's entry.
string ltrim( const string &str, const string &whitespace = "\t ")
{
int idx = str.find_first_not_of(whit
if( idx != string::npos )
return str.substr(idx);
return "";
}
string rtrim( const string &str, const string &whitespace = "\t ")
{
int idx = str.find_last_not_of(white
if( idx != string::npos )
return str.substr(0,idx+1);
return str;
}
string trim( const string &str, const string &whitespace = "\t ")
{
return rtrim(ltrim(str));
}
void main()
{
string str = " \t Hello sky ";
cout << "data >" << str << "***" << endl ;
cout << "left trim >" << ltrim(str) << "***" << endl ;
cout << "right trim >" << rtrim(str) << "***" << endl ;
cout << "trim >" << trim(str) << "***" << endl ;
}