Depurando programas com argumentos em C++
Programas executados pelo terminal podem receber argumentos. Esses são textos e números descritos logo após digitar o nome do programa.
Até agora, utilizamos argumentos para listar os arquivos *.cpp quando chamamos o Clang.
Vamos criar um programa simples que captura o nome de um usuário como argumento e o exibe numa mensagem de boas-vindas.
Projeto
Seção intitulada “Projeto”Crie uma pasta chamada hello_user dentro de dev/c_cpp_projects e navegue para dentro dela.
mkdir -p ~/dev/c_cpp_projects/hello_usercd ~/dev/c_cpp_projects/hello_userCrie a pasta .vscode e, dentro dela, os arquivos tasks.json e launch.json.
mkdir -p .vscodetouch .vscode/tasks.json .vscode/launch.jsonAbra o VSCode na pasta atual.
code .Então, crie o arquivo .gitignore na raiz do projeto, e o preencha com o snippet gitignore-c-cpp.
Finalmente, crie um arquivo chamado main.cpp na raiz do projeto .e o preencha com o código a seguir.
#include <iostream>
using namespace std;
int main() { cout << "Hello, world!"<< endl;
return 0;}A estrutura de pastas deve ficar da seguinte forma.
Directorydev
Directoryc_cpp_projects
Directoryhello_user
Directory.vscode
- launch.json
- tasks.json
- .gitignore
- main.cpp
Compilação
Seção intitulada “Compilação”Utilize o snippet tasks-json para inicializar o arquivo tasks.json com o seguinte código:
{ "version": "2.0.0", "tasks": []}Utilize o snippet cpp-build-task para preencher o vetor tasks.
O conteúdo do arquivo será o seguinte:
{ "version": "2.0.0", "tasks": [ { "args": [ "-fcolor-diagnostics", "-fansi-escape-codes", "-g", "${workspaceFolder}/*.cpp", "-I", "${workspaceFolder}", "-o", "${workspaceFolder}/build/${workspaceFolderBasename}" ], "command": "clang++", "detail": "Tarefa de compilação de um projeto em C++. Compila todos os arquivos C++ na raiz do projeto em um único executável.", "group": { "kind": "build" }, "label": "Clang: build C++ project (Local)", "options": { "cwd": "${workspaceFolder}" }, "problemMatcher": ["$gcc"], "type": "cppbuild" } ]}Execução
Seção intitulada “Execução”Então, utilize o snippet launch-json para inicializar o arquivo launch.json com o seguinte código:
{ "configurations": [], "version": "0.2.0"}Por fim, utilize o snippet cpp-launch para preencher o vetor configurations.
O conteúdo do arquivo será o seguinte:
{ "configurations": [ { "args": [], "cwd": "${workspaceFolder}", "name": "LLDB: build and launch C++ project (Local)", "preLaunchTask": "Clang: build C++ project (Local)", "program": "${workspaceFolder}/build/${workspaceFolderBasename}", "request": "launch", "terminal": "console", "type": "lldb" } ], "version": "0.2.0"}Argumentos
Seção intitulada “Argumentos”Para obtermos os argumentos passados para o programa, precisamos fazer uma pequena alteração na função main.
Vamos incluir nela os parâmetros int argc e char *argv[].
int main(int argc, char *argv[]) { cout << "Hello, world!"<< endl;
return 0;}- O parâmetro
int argcrepresenta a quantidade de argumentos que o usuário informou para o programa. - Já o parâmetro
char *argv[]se trata de um vetor de strings que guarda cada argumento informado.
Programa
Seção intitulada “Programa”O primeiro argumento da lista é sempre o caminho (ou path) do arquivo executável chamado.
Podemos conferir isso com uma modificação no nosso programa.
Vamos receber o argumento de índice 0 em uma variável.
Então, imprimiremos seu valor.
Edite o arquivo main.cpp da seguinte forma:
int main(int argc, char *argv[]) { auto program = argv[0]; cout << "This is the program " << program << "." << endl;
return 0;}Para executar nosso programa, acesse o menu de depuração clicando no ícone de bug ou pelo atalho
A execução será exibida na aba Debug console.
Você pode acessá-la com o atalho
Opcionais
Seção intitulada “Opcionais”Agora, vamos receber o segundo argumento, em que o usuário informará seu nome.
Em todos os programas, devemos tratar os argumentos de índice 1 em diante como opcionais.
De fato, o usuário não é obrigado a fornecê-los.
Assim, é nossa responsabilidade tratar esse caso.
A primeira forma de tratar a entrada de dados é verificar a quantidade de argumentos fornecidos.
- Caso ela seja igual a
1, então apenas o próprio programa foi chamado. - De
2em diante, sabemos que o usuário informou pelo menos um argumento.
Vamos fazer essa verificação. Caso o nome do usuário não tenha sido fornecido, imprimiremos que ele é um usuário desconhecido.
Edite o arquivo main.cpp da seguinte forma:
int main(int argc, char *argv[]) { auto program = argv[0]; cout << "This is the program " << program << "." << endl;
cout << "Hello, ";
if (argc < 2) { cout << "unknown user"; }
cout << "!" << endl;
return 0;}Compile o programa pelo VSCode.
Você pode utilizar o atalho Clang: build C++ project (Local).
Vamos executar o programa via linha de comando.
Lembre-se de que, quando o programa é compilado automaticamente pelo VSCode, seu arquivo executável fica dentro da pasta build.
./build/hello_user# This is the program ./build/hello_user.# Hello, unknown user!Nesse caso, como chamamos o programa manualmente pelo caminho ./build/hello_user, este foi impresso no terminal.
Na linha abaixo, o programa imprimiu que somos um usuário desconhecido.
Agora, vamos tratar um argumento recebido.
Caso o número de argumentos fornecido seja pelo menos 2, receberemos aquele de índice 1 em uma variável.
Nesse caso, poderemos imprimi-lo como o nome do usuário.
Edite o arquivo main.cpp da seguinte forma:
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) { auto program = argv[0]; cout << "This is the program " << program << "." << endl;
cout << "Hello, ";
if (argc < 2) { cout << "unknown user"; } else { auto name = argv[1]; cout << name; } cout << "!" << endl;
return 0;}Compile o projeto pelo VSCode como fizemos anteriormente.
Agora, ao executarmos o programa manualmente, vamos passar um nome. Ele deve ser escrito logo após o caminho do executável, e separado por um espaço. Também não devemos usar aspas ou qualquer outro delimitador.
./build/hello_user Gabriel# This is the program ./build/hello_user.# Hello, Gabriel!Parece ótimo!
Mas e se quisermos executar o programa pelo VSCode? Ele não sabe qual é o nome do usuário a informar.
Se tentarmos executá-lo, veremos a seguinte saída no “Debug console”:
# This is the program /home/gabriel/dev/c_cpp_projects/hello_user/build/hello_user.# Hello, unknown user!Podemos resolver isso editando o arquivo .vscode/launch.json.
O vetor args guarda a lista de argumentos a serem informados para o programa.
Vamos adicionar dentro dele a string “Alice”.
{ "configurations": [ { "args": ["Alice"], "cwd": "${workspaceFolder}", "name": "LLDB: build and launch C++ project (Local)", "preLaunchTask": "Clang: build C++ project (Local)", "program": "${workspaceFolder}/build/${workspaceFolderBasename}", "request": "launch", "terminal": "console", "type": "lldb" } ], "version": "0.2.0"}Agora, se compilarmos e executarmos pelo VScode, o resultado no “Debug console” mostrará o nome “Alice”, como a seguir:
# This is the program /home/gabriel/dev/c_cpp_projects/hello_user/build/hello_user.# Hello, Alice!Não se esqueça de inicializar o repositório e fazer commit das modificações.