【问题标题】:C++ Strings: size_t and string::nposC++ 字符串:size_t 和 string::npos
【发布时间】:2020-05-18 17:40:55
【问题描述】:

我是一名初级程序员,我正在尝试理解这段代码及其工作原理......

代码如下:

#include <iostream>
#include <string>  //C++ Strings Library
using namespace std;

int main() {
  string s1 {};
  string wordFind {};
  s1 = "The secret word is Boo";
    cout << "Enter the word to find: ";
    cin >> wordFind;
    size_t position = s1.find(wordFind);
     if (position != string::npos)
        cout << "Found " << wordFind << " at position: " << position << endl;
     else
        cout << "Sorry! " << wordFind << " not found" << endl;
    return 0;
}

这些是我实际遇到的问题:

  1. 什么是size_t,我们应该在什么时候准确地使用它们?(我只知道我们应该将它们用于数组索引和循环计数)
  2. 为什么我们在这里使用size_t?不能这样吗?:

position = s1.find(wordFind);

  1. 位置到底是什么?(我的意思是它是由 C++ 组成的还是它的一部分?)
  2. if 条件是否意味着搜索单词直到字符串的末尾?

编辑:谢谢大家帮助我...我很感激:)

【问题讨论】:

  • position = s1.find(wordFind); 缺少变量 position 的类型。我不知道您对“它是由它组成还是它是 C++ 的一部分?”是什么意思。关于size_t 参见例如What's the difference between size_t and int in C++?。关于if 条件见What does string::npos mean
  • 我认为你应该读一些 c++ 的书,因为你需要知道一些东西不能包含在一个答案中
  • @anonymous 是的,你是对的......我绝对应该......现在我正在从 Frank mitropoulos 和互联网制作的 udemy 课程中学习 :))
  • @DavidPeterson size_t 只是一种类型,例如intposition 只是一个任意变量名。我赞同阅读good book 的建议。所有这些都应该在入门课程或书籍中阐明。
  • size_t 应该在以下情况下使用: 1. 您想要一些东西来表示索引并且您没有对其进行任何算术运算;或者 2. 您希望它使用超出 @ 范围的值987654336@。否则默认使用int

标签: c++ c++11 c++14


【解决方案1】:

什么是size_t,我们应该在什么时候准确地使用它们?(我只知道我们应该将它们用于数组索引和循环计数)

size_t 是一个无符号整数类型,其大小足以表示 C++ 中任何对象的大小,包括数组类型。 (大小以它占用多少内存为单位)。

为什么我们在这里使用size_t

因为它通常足够大,如果字符串大于 int 可以存储的最大数量,使用类似 int 的内容是不够的。学究式地,您应该使用std::string::size_type,它保证能够容纳std::string 的大小,无论它有多大。

不能这样吗?:position = s1.find(wordFind);

不,您必须指定position 的类型。或者,您可以使用autoauto position = s1.find(wordFind);

位置到底是什么?(我的意思是它是由 C++ 组成的还是它的一部分?)

只是一个变量,表示您正在搜索的子字符串(单词)的索引。

if 条件是否意味着搜索单词直到字符串的末尾?

它正在检查是否找到了该单词。 std::string::npos 是一个特殊的数字 std::string::find 在未找到寻找的子字符串时返回。

【讨论】:

  • 谢谢...不过有一件事...是我们自己将其命名为“位置”还是必须完全是位置?
  • @DavidPeterson 你可以随意命名。这不是一个特殊的名字
【解决方案2】:

首先让我们说恕我直言,std::string 是一种蹩脚的字符串类设计,或者至少 - 从几个方面肯定显示了它的年龄。

  1. 什么是size_t,我们应该在什么时候使用它?

Thisstd::size_t(在 C++ 中它不是只是 size_t)。但是我们不要谈论什么时候应该使用它,因为......

  1. 为什么我们在这里使用size_t

我会说我们不应该这样做。我们应该写

auto position = s1.find(wordFind);

(就像您实际建议的那样,但使​​用auto 表示自动类型推断), 或者如果我们想明确一点,那么:

std::string::size_type position = s1.find(wordFind);

因为这就是 find() 返回的内容。 std::size_t 经常发生,但是:(a) 也许不是,我什至不确定(感谢@Ayxan); (b) 通常你不应该关心它是否是std::size_t

但即使是上述选项也不正确。这里有一个更深层次的问题——问题是find() 应该真的返回一个[std::optional][2]&lt;std::string::size_type&gt;。除了 C++ 直到最近才具有可选类型,所以字符串类有点像 jerry-rigged 它。未能找到子字符串会返回一个被奉为固有无效的值:std::string::npos(其类型为 std::string::size_type)。所以也许我们应该写的是:

auto to_optional = [](std::string::size_type pos_or_npos) { 
   return pos_or_npos == std::string::npos ? 
       std::nullopt : 
       std::optional<std::string::size_type>{pos_or_npos};
};
auto position = to_optional(s1.find(wordFind));

这更像我们的实际意思:要么你得到了一些职位,要么你没有。

  1. 位置到底是什么?(我的意思是它是由 C++ 组成的还是它的一部分?)

请看我的最后一段。

  1. if 条件是否意味着搜索单词直到字符串的末尾?

不,find() 已经搜索到最后。通过我们的重铸,if() 看起来像:

if (position.has_value()) 
// ... etc etc
else
// ... etc etc

【讨论】:

  • "恰好是 std::size_t" 不一定。不一定是std::size_t
  • @Ayxan:感谢您的 cmets,已编辑。我防御性地写typename;我们不需要它,因为std::string 是具体类型,而不是模板,对吧? (尽管 C++20 中的 IIRC 我们无论如何都不需要它)。
  • 是的,完全正确。因为它是一个具体的类型。
猜你喜欢
  • 1970-01-01
  • 2020-11-30
  • 2011-06-06
  • 2016-03-06
  • 2014-01-08
  • 1970-01-01
  • 2016-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多