Getting two warning when i run this program and i can't figure out how to stop this from happening. Any help would be appreciated!
warning: comparison between signed and unsigned integer expressions
Is the warning I'm getting for 2 lines in the extract_word function.
#include<iostream>
#include<string>
using namespace std;
class StringModify {
public:
void get_data();
//takes a line of input from the user
string& extract_word(string& a);
//extracts each word from the input line
string& reverse_word(string& s);
//returns a string which is reverse of s
void rev();
void swap(char& v1, char& v2);
//interchanges value of v1 and v2
void append(const string& reverse_word);
//puts together each reversed word with whitespaces to get formatted_line
void display();
//diss both input line and formatted_line
private:
string origional_string; //original string
string formatted_string; //formatted string
string word;
};
int main() {
StringModify data1;
//data1 becomes the call for class StringModify
data1.get_data();
// Exicution of get_data in class StringModify
data1.rev();
// Exicution of rev in class StringModify
data1.display();
// Exicution of display in class StringModify
return 0; }
void StringModify::get_data() {
cout << "Enter the string: ";
getline(cin, origional_string); }
string& StringModify::extract_word(string& a) {
size_t position = a.find(" ");
if(position != -1)
{
word = a.substr(0, position);
a.eras开发者_运维技巧e (0, position + 1);
}
else
{
word = a;
a = "";
}
return word; }
string& StringModify::reverse_word(string& s) {
for(int i = 0; i < s.length() / 2; i++)
{
swap(s[i], s[s.length() - 1 - i]);
}
return s; }
void StringModify::rev() {
string copy = origional_string;
while (!copy.empty())
{
append(reverse_word(extract_word(copy)));
} }
void StringModify::swap(char& v1, char& v2) {
char temp = v1;
v1 = v2;
v2 = temp; }
void StringModify::append(const string& reverse_word) {
formatted_string += reverse_word + " "; }
void StringModify::display() {
cout << "\nThe original string: "
<< origional_string << "\n"
<< "\nThe formatted string: "
<< formatted_string << "\n"; }
You assign the result of a.find(" ")
to a size_t
. size_t
is an unsigned type; it can never have a negative value.
Note that that does not mean the comparison will never be true. The -1
will be converted to be unsigned so the comparison can be performed (this is part of what are called the usual arithmetic conversions). When you convert -1
to be unsigned, it yields the largest value representable by the unsigned type. So, if find()
returns the largest possible size_t
, then the comparison will yield true.
To resolve the warning, you should compare against std::string::npos
, which is the value returned from find()
if the element is not found.
Use string::npos instead of -1
size_t
is an unsigned type and can therefore "never" be equal to -1
. The reason I have never
inside quotes is because it may well compare equal to -1
in some circumstances but that's only because either it or the -1
has been morphed into the other data type.
string::find
is documented to return string::npos
if the string can't be found and that's what you should compare your return value with (it's the size_t
equivalent of -1
anyway but done in such a way that you won't get warnings).
size_t is an unsigned integer and you are comparing it to -1. You need to change it's type to something else.
Looking at the code:
size_t position = a.find(" ");
if(position != -1)
...the warning is because size_t
is an unsigned type, so it can never actually be -1. In reality, the comparison can succeed, but only because -1 gets converted to a size_t
before the comparison (in the process becoming the largest value possible for a size_t
). If you're aware of that, and want it to happen, explicitly casting -1 to a size_t
will usually eliminate the warning. To be technically correct, it would probably be better to use std::string::npos
instead of -1 though.
Better still would be to eliminate all of this by (for example) putting your string into a stringstream
, and extracting words with operator>>
.
Edit: Since this seems like a somewhat interesting (and common) problem, I decided to write my own version for fun. You'd better not turn this in unless you study it really carefully, because I can practically guarantee that any prof seeing this will have a lot of questions (and if you give any wrong answers, the question you'll need to work on is "Would you like fries with that?):
#include <string>
#include <iostream>
#include <iterator>
class rev_string {
std::string data;
public:
rev_string(std::string const &input) {
data.assign(input.rbegin(), input.rend());
}
friend std::ostream &operator<<(std::ostream &os, rev_string const &r) {
return os << r.data;
}
};
int main() {
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::ostream_iterator<rev_string>(std::cout, " "));
return 0;
}
Note that there's really a much cleaner way to do this (using std::transform
), but it's not quite obscure enough looking to guarantee setting off alarms when/if a prof sees it, so I'm not posting it (at least for now).
精彩评论