Search code examples
c++c++23

Why is my std::string.contains() not working?


I am currently learning about reading and writing files in C++, I use Visual Studio Code, and I have my c_cpp_properties.json set: "cppStandard": "c++23".

This program is about reading a file named romeoandjuliet.txt and the user types a word to see if it appears in the .txt file, counting the number of appearances.

#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <cctype>
#include <string>
#include <vector>
#include <cmath>
#include <memory>
#include <fstream>

using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;

int main()
{
    string find{};
    string word{};
    int word_counter{0};
    int matches{0};
    std::ifstream reader;

    reader.open("romeoandjuliet.txt");

    if (!reader)
    {
        cerr << "'romeoandjuliet.txt' wasn't found" << endl;
    }
    cout << endl
         << "Enter the substring to search for: ";
    cin >> find;

    while (reader >> word)
    {
        if (word.contains(find))
        {
            matches++;
        }
        word_counter++;
    }

    cout << word_counter << " words were searched..." << endl
         << "The substring " << find << " was found " << matches << " times" << endl;

    return 0;
}

I don't know if it is due to my IDE configuration, or compiler, or my code, but the error I got from compiler says: 'std::string' {aka 'class std::__cxx11::basic_string<char>'} has no member named 'contains'

SOLUTION: Manual compile worked, so I looked what was my VS Code C++ build version, solution was to add "-std=c++23" in the "args" section on the tasks.json file


Solution

  • I suppose you use GCC as compiler. std::string::contains requires C++23 and at least GCC 11. Check cppreference.com for feature support of compilers and standard libraries.

    You can test which version of GCC is installed by:

    g++ --version
    

    To compile your file in C++23 mode you can use:

    g++ -std=c++23 file.cpp
    

    If you use CMake you can set:

    set(CMAKE_CXX_STANDARD 23)
    

    A full CMakeLists.txt example that works with any compiler is:

    # set minimum CMake major and minor version
    cmake_minimum_required(VERSION 3.10)
    
    # set your project name
    project(Tutorial)
    
    # force at least C++23 as standard
    set(CMAKE_CXX_STANDARD 23)
    
    # create an executable from source files
    add_executable(Tutorial file1.cpp file2.cpp)
    

    Note that your compiler compiler may not have full support for C++23 yet. If you want to use specific features anyway, you can use the feature test macros to ensure they are already supported. In case of std::string::contains you can use in your file.cpp:

    #include <string>
    
    #ifndef __cpp_lib_string_contains
    #error "The standard library doesn't support std::string::contains()."
    #endif
    

    If you compile this with GCC 11 and C++23 it works fine. If you use an older standard like C++20 you will get an error like:

    user@pc:~$ c++ -std=c++20 file.cpp 
    file.cpp:4:2: error: #error "The standard library doesn't support std::string::contains()."
        4 | #error "The standard library doesn't support std::string::contains()."
          |  ^~~~~