How to check if string ends with .txt

后端 未结 11 1771
耶瑟儿~
耶瑟儿~ 2020-12-15 04:23

I am learning basic C++, and right now I have gotten a string from a user and I want to check if they typed the entire file name (including .txt) or not. I have the string,

11条回答
  •  执笔经年
    2020-12-15 05:06

    You've gotten quite a few answers already, but I decided to add yet another:

    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;
    }
    

    Since you have gotten quite a few answers, perhaps a quick test and summary of results would be worthwhile:

    #include 
    #include 
    #include 
    #include 
    #include 
    
    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 
    bool test(std::string const &label, F f) {
        static const std::vector> 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);
    }
    

    Results with gcc:

    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
    

    Results with 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
    

    Yes, those were run on identical hardware, and yes I ran them a number of times, and tried different optimization options with g++ to see if I could get it to at least come sort of close to matching VC++. I couldn't. I don't have an immediate explanation of why g++ produces so much worse code for this test, but I'm fairly confident that it does.

提交回复
热议问题