Предупреждения в домашней задаче C ++ - PullRequest
0 голосов
/ 22 ноября 2010

Получение двух предупреждений, когда я запускаю эту программу, и я не могу понять, как этого избежать. Любая помощь будет оценена!

предупреждение: сравнение целых выражений со знаком и без знака

Это предупреждение для двух строк в функции extract_word.

#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.erase (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"; }

Ответы [ 5 ]

7 голосов
/ 22 ноября 2010

Вы присваиваете результат a.find(" ") для size_t.size_t - беззнаковый тип;оно никогда не может иметь отрицательного значения.

Обратите внимание, что это не означает, что сравнение никогда не будет верным.-1 будет преобразовано в беззнаковое, чтобы можно было выполнить сравнение (это часть того, что называется обычным арифметическим преобразованием).Когда вы преобразуете -1 в беззнаковое, оно дает наибольшее значение, представляемое беззнаковым типом.Таким образом, если find() возвращает максимально возможное значение size_t, то сравнение даст значение true.

Чтобы устранить предупреждение, следует сравнить с std::string::npos, то есть значением, возвращаемым из find(), еслиэлемент не найден.

4 голосов
/ 22 ноября 2010

Используйте строку :: npos вместо -1

4 голосов
/ 22 ноября 2010

size_t является беззнаковым типом и поэтому может никогда не быть равным -1.Причина, по которой у меня есть never внутри кавычек, заключается в том, что в некоторых обстоятельствах она вполне может сравниваться с -1, но это только потому, что либо она, либо -1 преобразованы в другой тип данных.

string::find - это задокументировано для возврата string::npos, если строка не может быть найдена, и это , с чем следует сравнить возвращаемое значение (это size_t равнозначно -1 в любом случае, но сделано так, что вы не получите предупреждений).

2 голосов
/ 22 ноября 2010

Глядя на код:

    size_t position = a.find(" ");

    if(position != -1)

... предупреждение связано с тем, что size_t - это тип без знака, поэтому он никогда не может быть -1. В действительности сравнение может быть успешным, но только потому, что -1 преобразуется в size_t перед сравнением (в процессе становится наибольшим возможным значением для size_t). Если вы знаете об этом и хотите, чтобы это произошло, явное приведение -1 к size_t обычно устраняет предупреждение. Чтобы быть технически правильным, вероятно, было бы лучше использовать std::string::npos вместо -1.

Еще лучше было бы устранить все это, например, поместив вашу строку в stringstream и выделив слова с помощью operator>>.

Редактировать: Поскольку это кажется довольно интересной (и распространенной) проблемой, я решил написать свою собственную версию для удовольствия. Вам лучше не сдавать это, если вы не изучите это действительно тщательно, потому что я могу практически гарантировать, что у любого профессора, увидевшего это , будет много вопросов (и если вы дадите какой-нибудь ответы, вопрос, над которым вам нужно будет поработать: «Хотели бы вы с этим жарить?):

#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;
}

Обратите внимание, что на самом деле есть гораздо более чистый способ сделать это (используя std::transform), но он не совсем неясен, чтобы гарантировать отключение сигналов тревоги, когда / если его видит проф, поэтому я не публикую его (в хотя бы пока).

2 голосов
/ 22 ноября 2010

size_t - целое число без знака, и вы сравниваете его с -1.Вам нужно изменить его тип на что-то другое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...