如何读取字符串中的最后一个字符

时间:2019-08-19 00:44:58

标签: c++

我试图打印字符串的最后一个字符,例如str [] =“ This is an example”,我尝试使用某些函数来打印“ example”的'e',但它们都不像我期望。我知道在代码中写入最后一个字符的位置编号更为简单,但是与strrchr函数一样,代码本身也可以工作。有没有类似的功能?

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main ()
{
    char str[] = "This is an example";
    char * pch;
    pch=strrchr(str,'s');

    cout<<str<<endl;
    cout<<"Last time 's' was found was in position: "<<pch-str+1<<endl;
    cout<<"Last character in this example is "<<str[X];
    return 0;
}

4 个答案:

答案 0 :(得分:3)

来自the documentation for strrchr

  

终止的空字符被视为C字符串的一部分。因此,也可以将其定位为检索指向字符串末尾的指针。

因此,strrchr(str, '\0')[-1]将具有最后一个字符。请注意,只有在您确定str不为空时,这才是安全的。

答案 1 :(得分:1)

我假设您选择char []以避免分配或类似操作,所以不打算讨论std :: string作为选择。

三种解决方案,一种在现代C ++中使用string_view,一种使用模板; 另一种使用std :: size和index运算符。

解决方案1.1:

我建议您使用它,它几乎是最佳的,并且比替代方法更具可读性。不需要那么多的样板即可处理空字符串或没有空终止的字符串。

#include <string_view>
#include <iostream>

int main()
{
    std::string_view str = "This is an example";
    auto X = str.find_last_of('s');
    //
    // Make sure the character exists in the string
    if (X != std::string_view::npos)
    {
        std::cout<< str << std::endl;
        std::cout<< "Last time 's' was found was in position: " << X << std::endl;
    }
    else
    {
        std::cout<<"Character did not exist in string.\n";
    }
    if (!str.empty()) std::cout<< "Last character in this example is " << str.back();
    else std::cout << "Cannot get the last character in an empty string!";
    return 0;
}

您可以在此处运行解决方案: https://onlinegdb.com/SJK2hjPEB

相同的代码将与std :: string一起使用。

解决方案1.2

这是仅 的编译时解决方案,它依赖于被聚合构造或构造为字符串的字符串。

template <size_t N>
constexpr char LastCharacter(char (&input)[N])
{
    static_assert(N >= 1, "A character array representing a string must have atleast 1 character AND a null terminator.");
    return (input[N - 1] == '\0') ? input[N - 2] : input[N - 1];
}

此处显示的测试和示例: https://onlinegdb.com/HJ_IXEd4H

解决方案2

这具有必需的检查,以避免出现空字符串问题。 在此版本中,有一个空数组是一个编译时错误。 str [] =“”不是一个空数组,它有1个字符,为空。空字符串没有最后一个字符,需要对此进行处理。也应在strrchr中对其进行处理。

如果必须使用strrchr(...),请考虑检查结果是否为nullptr。如果返回nullptr,则在字符串中找不到该字符:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cassert>
using namespace std;

int main ()
{
    char str[] = {'h', 'e','l', 'l', 'o', '\0'};
    //
    // Prevent use with an empty array (1 character + 1 null character minimum)
    if (std::size(str) > 1)
    {
        //
        // Only allow null terminated strings.
        assert( str[std::size(str) - 1] == '\0' );
        //
        // There skip the last null character and get the last character
        // No null character, not compensation needed
        cout<<"Last character in this example is "<< str[ std::size(str) - 2 ];
    }
    else
    {
        cout << "Cannot process empty string\n";
    }
    return 0;
}

https://onlinegdb.com/SkrP2Q_NB

请注意,将字符串定义为数组可使字符串不存在空终止符而存在。在这种情况下,上述解决方案将不起作用。如果要处理这种情况,则需要检查是否存在空终止符,如果存在,请在代码中进行补偿。如果没有空终止符,则assert会导致错误。

-

详细说明strrchr的问题。该函数需要以null结尾的字符串。

  

终止的空字符被视为C字符串的一部分。   因此,也可以将其定位为检索指向末尾的指针   一个字符串。

http://www.cplusplus.com/reference/cstring/strrchr/ 先前的答案引用了这一点,但在这里也出于完整性考虑。

您使用的数据类型允许字符数组没有空终止:

char data[] = {'a', 'b', 'c'};

这就是断言在解决方案2中的处理方式。

答案 2 :(得分:1)

简单:使用标准的strlen函数,如下所示:

int main ()
{
    char str[] = "This is an example";
    char * pch;
    pch=strrchr(str,'s');

    cout<<str<<endl;
    cout<<"Last time 's' was found was in position: "<<pch-str+1<<endl;
    size_t X = strlen(str) - 1; // X will be the index of the last character!
    cout<<"Last character in this example is "<<str[X];
    return 0;
}

或者,只是为了好玩,如果您想处理字符串可能为空的情况:

    size_t X = strlen(str); X -= !!X; // Non-zero: decrement, Zero: Leave as is
    cout<<"Last character in this example is "<<str[X];

然后,对于空字符串,cout << str [X]将显示实现对NULL字符所做的任何操作。

答案 3 :(得分:0)

如果您不介意使用std::string,此代码段就可以完成工作。

#include <string>
#include <iostream>

int main() {
    std::string str = "This is some text";
    std::cout << str.back() << std::endl;

}