Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查字符串是否以.txt结尾 我正在学习基本C++,现在我从用户那里得到了一个字符串,我想检查他们是否输入了整个文件名(包括.txt)。我有字符串,但如何检查字符串是否以“.txt”结尾 字符串文件名; cout>文件名; string txt=fileName.Right(4);_C++_String - Fatal编程技术网

如何检查字符串是否以.txt结尾 我正在学习基本C++,现在我从用户那里得到了一个字符串,我想检查他们是否输入了整个文件名(包括.txt)。我有字符串,但如何检查字符串是否以“.txt”结尾 字符串文件名; cout>文件名; string txt=fileName.Right(4);

如何检查字符串是否以.txt结尾 我正在学习基本C++,现在我从用户那里得到了一个字符串,我想检查他们是否输入了整个文件名(包括.txt)。我有字符串,但如何检查字符串是否以“.txt”结尾 字符串文件名; cout>文件名; string txt=fileName.Right(4);,c++,string,C++,String,Right(int)方法仅适用于CString,因此上述代码不起作用。如果可能的话,我想使用常规字符串。有什么想法吗?使用boost谓词: #include <boost/algorithm/string/predicate.hpp> if (boost::ends_with(fileName, ".txt")) { /* ... */ } #包括 if(boost::以(fileName,.txt“)结尾){/*…*/} 不幸的是,这个有用的函数不在标准库中。写起来很容易 bo

Right(int)
方法仅适用于CString,因此上述代码不起作用。如果可能的话,我想使用常规字符串。有什么想法吗?

使用boost谓词:

#include <boost/algorithm/string/predicate.hpp>

if (boost::ends_with(fileName, ".txt")) { /* ... */ }
#包括
if(boost::以(fileName,.txt“)结尾){/*…*/}

不幸的是,这个有用的函数不在标准库中。写起来很容易

bool has_suffix(const std::string &str, const std::string &suffix)
{
    return str.size() >= suffix.size() &&
           str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

最简单的方法可能是验证字符串长度是否足以容纳
“.txt”
,并查看是否可以在
size()-4
位置找到字符串,例如:

bool ends_with_string(std::string const& str, std::string const& what) {
    return what.size() <= str.size()
        && str.find(what, str.size() - what.size()) != str.npos;
}
bool以字符串结尾(std::string const&str,std::string const&what){
返回所需的.size()使用


您可以使用另一个字符串验证扩展名,如下所示:

string fileName;

cout << "Enter filename: \n";
cin >> fileName;

//string txt = fileName.Right(4);
string ext="";
for(int i = fileName.length()-1;i>fileName.length()-5;i--)
{
    ext += fileName[i];
}
cout<<ext;
if(ext != "txt.")
    cout<<"error\n";
字符串文件名;
cout>文件名;
//string txt=fileName.Right(4);
字符串ext=“”;
对于(int i=fileName.length()-1;i>fileName.length()-5;i--)
{
ext+=文件名[i];
}
cout以下是“完全自行编写”的解决方案:

bool isEndsWith(const std::string& pstr, const std::string& substr) const
{
    int tlen = pstr.length();
    int slen = substr.length();

    if(slen > tlen)
        return false;

    const char* tdta = pstr.c_str();
    const char* sdta = substr.c_str();

    while(slen)
    {
        if(tdta[tlen] != sdta[slen])
            return false;

        --slen; --tlen;
    }
    return true;
}

不幸的是,这是标准库中不存在的东西,编写它也有点烦人。这是我的尝试:

bool ends_with(const std::string& str, const std::string& end) {
    size_t slen = str.size(), elen = end.size();
    if (slen < elen) return false;
    while (elen) {
        if (str[--slen] != end[--elen]) return false;
    }
    return true;
}
bool以(const std::string&str,const std::string&end)结尾{
size_t slen=str.size(),elen=end.size();
如果(slen
您已经得到了很多答案,但我决定再添加一个:

bool ends_with(std::string const &a, std::string const &b) {
    auto len = b.length();
    auto pos = a.length() - len;
    if (pos < 0)
        return false;
    auto pos_a = &a[pos];
    auto pos_b = &b[0];
    while (*pos_a)
        if (*pos_a++ != *pos_b++)
            return false;
    return true;
}
使用VC++的结果:

Testing: Jerry Coffin           0.718 Seconds
Testing: Dietrich Epp           0.982 Seconds
Testing: Dietmar                1.087 Seconds
Testing: Roman                  0.883 Seconds
Testing: 6502                   0.927 Seconds
Testing: rajenpandit            Failed

是的,这些都是在相同的硬件上运行的,是的,我运行了很多次,用g++尝试了不同的优化选项,看看是否能让它至少接近VC++。我不能。我不能立即解释为什么g++会为这个测试产生如此糟糕的代码,但我很有信心它确实如此.

2个选项,我可以在下面提到的选项中想到:
1) regex-prob在这方面做得太过分了,但是简单的regex很好,可读性也很好
2) rbegin-有点不错,可能是我遗漏了什么,但这是:

bool ends_with(const string& s, const string& ending)
{
return (s.size()>=ending.size()) && equal(ending.rbegin(), ending.rend(), s.rbegin());
}

这应该可以

bool ends_with(const std::string & s, const std::string & suffix) {
     return s.rfind(suffix) == s.length() - suffix.length();
}


我怀疑您的问题更多地与文件名有关,而不是与字符串有关,因此我建议您寻找以可移植方式提取文件扩展名的解决方案。许多库都提供了这方面的支持。如果
filename.size()<4
,则此问题可能会导致问题。如果
filename.size()<4
,则仍然会导致问题()<4
std::max()
函数在此处无法正常工作。提示:
std::max(0,filename.size()-4)=filename.size()-4始终。这仍然会导致问题。如何确保
(long)filename.size()在C++和C++中,有一个简单的整数减法,有多少陷阱,这是非常令人惊讶的。我不确定这是否是一个在推C++中的例子。当然不是你的错,当然是+1,但是为什么使用指针而不是只使用<代码> pSTR[-TLEN]!=子串[-SLIE]
在测试中?@6502好吧,我认为迪特里希的解决方案很好,但我在上第一堂课时就写了这篇文章,直到现在还在我的引擎中使用:)每个人都有年轻时写的不好的代码。但为什么要坚持(除非你被迫这么做)?@6502,我认为我的解决方案还不足以优化它,即使是现在:)传播糟糕的编程风格:1-length()是无符号的。2-获取
const char*
完全没有必要。谢谢。但是现在我想知道你为什么把传递的参数变成常量?bool有_后缀(std::string str,std::string suffix){}《编年史》:这是一个关于“为什么要使用常量”的一般性问题“
const
限定符是一个承诺,由编译器强制执行,即函数中的代码不会修改字符串。由于函数不修改字符串,您最好做出该承诺,然后可以向函数传递const字符串,而无需先复制它们。如果省略const,则可能需要c。”复制字符串,然后才能将其传递给函数。@Chronicle:快速搜索找到了好的材料,并通过轨道中的亮度竞赛给出了答案:@Chronicle在不更改参数时始终使用
const&
(只读访问)。即使你不明白为什么…还是去做吧。尽管如此,理解为什么还是很好。做我,做我,做我…:P除了上次我在互联网上读东西时g++的字符串实现糟糕之外;)又名no SSO@nosenseal:这些结果似乎肯定会支持这一点。'pos<0'总是错误的。length()返回无符号类型。只需显式比较std字符串长度,因为它们应该是O(1)最干净的解决方案,因此farThis是我的最爱。可以使用boost::iends_和(…)进行不区分大小写的比较。
#include <iostream>
#include <string>
#include <vector>
#include <time.h>
#include <iomanip>

bool ends_with(std::string const &a, std::string const &b) {
    auto len = b.length();
    auto pos = a.length() - len;
    if (pos < 0)
        return false;
    auto pos_a = &a[pos];
    auto pos_b = &b[0];
    while (*pos_a)
        if (*pos_a++ != *pos_b++)
            return false;
    return true;
}

bool ends_with_string(std::string const& str, std::string const& what) {
    return what.size() <= str.size()
        && str.find(what, str.size() - what.size()) != str.npos;
}

bool has_suffix(const std::string &str, const std::string &suffix)
{
    return str.size() >= suffix.size() &&
        str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

bool has_suffix2(const std::string &str, const std::string &suffix)
{
    bool index = str.find(suffix, str.size() - suffix.size());
    return (index != -1);
}

bool isEndsWith(const std::string& pstr, const std::string& substr)
{
    int tlen = pstr.length();
    int slen = substr.length();

    if (slen > tlen)
        return false;

    const char* tdta = pstr.c_str();
    const char* sdta = substr.c_str();

    while (slen)
    {
        if (tdta[tlen] != sdta[slen])
            return false;

        --slen; --tlen;
    }
    return true;
}

bool ends_with_6502(const std::string& str, const std::string& end) {
    size_t slen = str.size(), elen = end.size();
    if (slen <= elen) return false;
    while (elen) {
        if (str[--slen] != end[--elen]) return false;
    }
    return true;
}

bool ends_with_rajenpandit(std::string const &file, std::string const &suffix) {
    int pos = file.find(suffix);
    return (pos != std::string::npos);
}

template <class F>
bool test(std::string const &label, F f) {
    static const std::vector<std::pair<std::string, bool>> tests{
        { "this is some text", false },
        { "name.txt.other", false },
        { "name.txt", true }
    };
    bool result = true;

    std::cout << "Testing: " << std::left << std::setw(20) << label;
    for (auto const &s : tests)
        result &= (f(s.first, ".txt") == s.second);
    if (!result) {
        std::cout << "Failed\n";
        return false;
    }
    clock_t start = clock();
    for (int i = 0; i < 10000000; i++)
        for (auto const &s : tests)
            result &= (f(s.first, ".txt") == s.second);
    clock_t stop = clock();
    std::cout << double(stop - start) / CLOCKS_PER_SEC << " Seconds\n";
    return result;
}

int main() {
    test("Jerry Coffin", ends_with);
    test("Dietrich Epp", has_suffix);
    test("Dietmar", ends_with_string);
    test("Roman", isEndsWith);
    test("6502", ends_with_6502);
    test("rajenpandit", ends_with_rajenpandit);
}
Testing: Jerry Coffin           3.416 Seconds
Testing: Dietrich Epp           3.461 Seconds
Testing: Dietmar                3.695 Seconds
Testing: Roman                  3.333 Seconds
Testing: 6502                   3.304 Seconds
Testing: rajenpandit            Failed
Testing: Jerry Coffin           0.718 Seconds
Testing: Dietrich Epp           0.982 Seconds
Testing: Dietmar                1.087 Seconds
Testing: Roman                  0.883 Seconds
Testing: 6502                   0.927 Seconds
Testing: rajenpandit            Failed
bool ends_with(const string& s, const string& ending)
{
return (s.size()>=ending.size()) && equal(ending.rbegin(), ending.rend(), s.rbegin());
}
bool ends_with(const std::string & s, const std::string & suffix) {
     return s.rfind(suffix) == s.length() - suffix.length();
}