Search code examples
c++stringargv

Convert all and any command line input to string in C++


I am trying to write a small code at the beginning of my program that runs different functions depending on the file extension of the files that are passed when calling the program from the command line.

I want to convert argv[2] into a string (called st) that I can compare with ".png", ".txt", etc. using strccmp.

I found similar solutions around SO, but none of them addressed the issue of saving any argument into a string variable. Whenever I try to use something like argv[1] or argv[2], the debugger complains that the subscript is out of range, and I am at a loss about how to get around this.

int main(int argc, char** argv)
{
    // First and simplest attempt
    sd::string st = argv[2];

    // Second attempt that also fails
    std::vector<std::string> all_arg;

    if (argc > 1) {
        all_arg.assign(argv + 1, argv + argc);
    }

    std::string st = all_arg[2];


    // Comparison
    st = st.substr(st.size() - 4, st.size() - 1);
    if (strcmp(st.c_str(), ".png")) { ... }
    else {...}      

}

Solution

  • Corrected for obvious problems, your code compiles and runs just fine.

    #include <iostream>
    #include <vector>
    #include <string>
    
    int main( int argc, char ** argv )
    {
        std::vector< std::string > all_arg;
        if ( argc > 1 )
        {
            all_arg.assign( argv + 1, argv + argc );
        }
    
        for ( auto str : all_arg )
        {
            std::cout << str << "\n";
        }
    }
    

    As for your comparison, that looks fishy in more than one way...

    st = st.substr(check.size() - 4, check.size() - 1);
    

    Aside from check not being defined, what happens if your string is shorter than 4 characters...?

    if (strcmp(st.c_str(), ".png")) { ... }
    

    Err... degrading string to char array through c_str() and then going through the C function strcmp()? What is that for?

    Try something like this:

    for ( auto str : all_arg )
    {
        std::string extension;
        std::string::size_type length = str.length();
    
        if ( length >= 4 )
        {
             extension = str.substr( size - 4 );
        }
    
        if ( extension == ".png" )
        {
            std::cout << str << "is PNG!\n";
        }
    }
    

    And then think about the above being case-sensitive, and once you think about converting str to lowercase prior to comparing, consider locale, which might include Unicode. ;-)