作业问题 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";
【问题讨论】:
在要求解释时包含实际警告真的很有帮助。 为什么swap
、reverse_word
和extract_word
类方法根本不接触类成员?还要注意cplusplus.com/reference/algorithm/reverse的存在@
【参考方案1】:
您将a.find(" ")
的结果分配给size_t
。 size_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
未签名。 i
是 int
并因此被签名。要解决警告,您需要更改i
的声明以使其成为unsigned
(或size_t
或std::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>>
提取单词来消除所有这些。
编辑:由于这似乎是一个有点有趣(和常见)的问题,所以我决定编写自己的版本来娱乐。除非您真的仔细研究过,否则最好不要上交,因为我几乎可以保证任何教授看到此都会有很多问题(如果你给任何错误的答案,你需要解决的问题是“你想用那个炸薯条吗?):
#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++ 中的警告的主要内容,如果未能解决你的问题,请参考以下文章
Visual Studio Community 2019 中的 C++ 代码分析产生警告 C26486 和 C26414