Как добавить строку в argv

avatar
Gurnoor
1 июля 2021 в 18:46
133
2
1

Я хочу удалить файл, имя которого указано в аргументе программы; но, поскольку тип файла останется постоянным (.bat), я хочу, чтобы он автоматически задавался программой (например, запуск deletefile.exe script удалит "script.bat" (который находится в том же каталоге)). Я видел этот вопрос, но решение, похоже, не работает.

Я что-то неправильно понял?

Моя попытка ниже:

#include <iostream>
#include <fstream>
#include <string>


using namespace std;

int main(int argc, char *argv[]){

    if(argv[1] == string("del")){
        string file_to_remove;
        file_to_remove = argv[2]+".bat";
        if (remove(file_to_remove.c_str()) != 0){
            cout<<"Error in file deletion.\n";
        }
        else {
            cout<<"Removed alias " << argv[2] << "\n";
        }
    }
    return 0;
}

Но это приводит к ошибке компилятора

<source>: In function 'int main(int, char**)':
<source>:12:33: error: invalid operands of types 'char*' and 'const char [5]' to binary 'operator+'
   12 |         file_to_remove = argv[2]+".bat";
      |                          ~~~~~~~^~~~~~~
      |                                | |
      |                                | const char [5]
      |                                char*
Источник
Ruzihm
1 июля 2021 в 19:05
2

Отвечает ли это на ваш вопрос? c++ недопустимые операнды типов 'char*' и 'const char [2]' для двоичного 'operator+'

Adrian Mole
1 июля 2021 в 19:06
0

@Рузихм Ах! Я должен был искать дубликат. Тск.

Ruzihm
1 июля 2021 в 19:07
0

@AdrianMole Мне нравится ваш ответ ниже. Если он в конечном итоге будет закрыт, вы скопируете его в другой вопрос? я тоже там проголосую

Adrian Mole
1 июля 2021 в 19:46
1

@Ruzihm На самом деле, я не совсем уверен, что другой вопрос является дубликатом. Хотя, конечно, это тесно связано. Я не голосовал за закрытие, так как это было бы решающим (молотковым) голосованием.

Ответы (2)

avatar
Adrian Mole
1 июля 2021 в 18:53
3

В правой части оператора file_to_remove = argv[2]+".bat"; делается попытка объединить две строки char* с помощью оператора +; вы не можете этого сделать, и по крайней мере один из операндов должен быть преобразован в std::string.

Вы можете сделать это, создав временный std:string, например:

file_to_remove = string(argv[2]) + ".bat";

Или, более кратко (начиная с C++14), добавив суффикс s к строковому литералу:

file_to_remove = argv[2] + ".bat"s;
JDługosz
1 июля 2021 в 19:09
0

Суффикс s работает, только если вы включили его с помощью using пространства имен литералов.

avatar
JDługosz
1 июля 2021 в 19:08
3

Не писать using namespace std;.

Однако вы можете в файле CPP (не в файле H) или внутри функции поместить отдельные using std::string; и т. д. (см. SF.7.)


В предыдущем ответе Адриана уже объяснялось, что ваше использование + не сработало, потому что это еще не string. Но вы также объявили переменную в одной строке без инициализатора и назначили ее в следующей строке. Вы должны инициализировать переменные при их объявлении. Таким образом, было бы просто записать это как:

string file_to_remove = argv[2];
file_to_remove = += ".bat";

Однако обратите внимание, что существует тип специально для имен файлов!

std::filesystem::path file_to_remove = argv[2];
file_to_remove.replace_extension (".bat");

Это лучше, потому что он может определить, что расширение уже существует, и изменить его, а также предоставить другие формы манипулирования именами файлов.

if (remove(file_to_remove.c_str()) != 0){

Аналогичным образом существует функция filesystem::remove, которая является функцией C++ и принимает path объектpath, вместо того, чтобы создавать строку в стиле C, и напрямую возвращает строку в стиле C true в случае успеха.

std::error_code ec;
if (std::filesystem::remove(file_to_remove))  cout << "File removed\n";
else cout << "error was " << ec.message() << "\n";

Вы видите, что это также упрощает получение читаемого сообщения с подробным описанием фактической ошибки.

JDługosz
1 июля 2021 в 19:29
0

@ 463035818_is_not_a_number Я вставил его из другого ответа, где каждая тема была отдельной заголовком.

463035818_is_not_a_number
1 июля 2021 в 19:31
0

выглядит намного лучше ;)