作业问题 C++ 中的警告

Posted

技术标签:

【中文标题】作业问题 C++ 中的警告【英文标题】:Warnings in a homework problem C++ 【发布时间】:2010-11-22 05:56:28 【问题描述】:

当我运行这个程序时收到两个警告,我不知道如何阻止这种情况的发生。任何帮助,将不胜感激!

警告:有符号和无符号整数表达式之间的比较

是我在 extract_word 函数中收到的 2 行警告。

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

【问题讨论】:

在要求解释时包含实际警告真的很有帮助。 为什么swapreverse_wordextract_word类方法根本不接触类成员?还要注意cplusplus.com/reference/algorithm/reverse的存在@ 【参考方案1】:

您将a.find(" ") 的结果分配给size_tsize_t 是无符号类型;它永远不能有负值。

请注意,这并不意味着比较永远不会成立。 -1 将被转换为无符号的,因此可以执行比较(这是所谓的通常算术转换的一部分)。当您将-1 转换为无符号时,它会产生无符号类型可表示的最大值。因此,如果find() 返回最大可能的size_t,则比较结果为真。

要解决警告,您应该与std::string::npos 进行比较,如果未找到该元素,则该值是从find() 返回的值。

【讨论】:

对于我在 reverse_word 中遇到的错误我该怎么办。 s.length() 是问题所在。 你想使用 size_t 而不是 int。 @Alec:如果您要进行有符号/无符号转换,请将i 无符号。 @James 警告:有符号和无符号整数表达式之间的比较|也是我得到的那个,但我不能取消分配 i 或者它不知道从哪里开始循环,因为我会有一个随机变量,对吗? @Alec: s.length() 未签名,这意味着 s.length() / 2 未签名。 iint 并因此被签名。要解决警告,您需要更改i 的声明以使其成为unsigned(或size_tstd::string::size_type 或一些无符号类型)或使用强制转换将右侧转换为签名:@987654339 @。前一种方法要好得多,因为它不需要演员表并且更清楚地表达了您的意图。【参考方案2】:

使用 string::npos 代替 -1

【讨论】:

【参考方案3】:

size_t 是无符号类型,因此“从不”等于-1。我在引号内加上never 的原因是因为它在某些情况下可能与-1 相当,但这仅仅是因为它或-1 已转变为另一种数据类型。

string::find 是 documented,如果找不到字符串,则返回 string::npos这是您应该将返回值与什么进行比较(它是 size_t 等效于 @987654331 @ 无论如何,但以不会收到警告的方式完成)。

【讨论】:

【参考方案4】:

size_t 是一个无符号整数,您将它与 -1 进行比较。您需要将其类型更改为其他类型。

【讨论】:

【参考方案5】:

看代码:

    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&gt;&gt; 提取单词来消除所有这些。

编辑:由于这似乎是一个有点有趣(和常见)的问题,所以我决定编写自己的版本来娱乐。除非您真的仔细研究过,否则最好不要上交,因为我几乎可以保证任何教授看到此都会有很多问题(如果你给任何错误的答案,你需要解决的问题是“你想用那个炸薯条吗?):

#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),但它还不够晦涩难懂,无法保证当教授看到它时/如果它会发出警报,所以我没有发布它(在至少现在)。

【讨论】:

以上是关于作业问题 C++ 中的警告的主要内容,如果未能解决你的问题,请参考以下文章

如何处理 C++ 内联 + 模板上下文中的警告?

当我在 C++ 中的类中使用类时收到警告 [关闭]

C++ DLL中的导出类在编译时会发出警告[重复]

Visual Studio Community 2019 中的 C++ 代码分析产生警告 C26486 和 C26414

C++ 中的 Xor 加密,带有警告“使用带二进制位运算符的有符号整数操作数”

如何在 Gitlab 中完成工作并发出警告