Como você determina os caminhos completos dos argumentos da linha de comando do nome do arquivo em um programa C ++?
-
19-09-2019 - |
Pergunta
Estou escrevendo um programa em C ++ que aceita um nome de arquivo como um argumento na linha de comando:
>> ./myprogram ../path/to/file.txt
Eu sei que posso simplesmente abrir um Fream usando argv[1]
, mas o programa precisa de mais informações sobre a localização exata (por exemplo, nome completo) do arquivo.
Eu pensei em anexar argv[1]
para getcwd()
, no entanto, obviamente, no exemplo acima, você acabaria com /path/../path/to/file.txt
. Não tenho certeza se o FStream resolveria esse caminho automaticamente, mas mesmo se o fizesse, ainda não tenho o caminho completo sem muito processamento de string.
Obviamente, esse método não funcionaria se o caminho fornecido já fosse absoluto. E como este programa pode ser executado no Linux/Windows/etc, basta detectar um caractere inicial '/' não funcionará para determinar se o argumento era um caminho completo ou não.
Eu acho que esse é um problema bastante comum para lidar com nomes de caminhos em vários OSS. Então Como se recupere o nome do caminho completo de um argumento da linha de comando e Como isso é tratado entre os sistemas operacionais?
Solução
O manuseio do nome do caminho é altamente específico: alguns OS têm uma hierarquia com apenas uma raiz (por exemplo, no Unix), outros têm várias raízes em letras de acionamento de la ms-dos '; Alguns podem ter links simbólicos, links difíceis ou outros tipos de links, o que pode tornar a traversal complicada. Alguns podem nem ter o conceito de um caminho "canônico" para um arquivo (por exemplo, se um arquivo tiver links rígidos, ele tem vários nomes, nenhum dos quais é mais "canônico").
Se você já tentou fazer manipulação de caminho em vários sistemas operacionais em Java, sabe o que quero dizer :-).
Em resumo, o manuseio de nome do caminho é específico do sistema, portanto, você terá que fazê-lo separadamente para cada sistema operacional (família) ou usar uma biblioteca adequada.
Editar:
Você poderia olhar para Tempo de execução portátil do Apache, ou no Boost (C ++), ambos têm funções de manuseio de nome do caminho.
Outras dicas
... você acabaria com /path/../path/to/file.txt. Não tenho certeza se o FStream resolveria esse caminho automaticamente, mas mesmo se o fizesse, ainda não tenho o caminho completo sem muito processamento de string.
Faz, e você pode usar/path/../path/ para tudo o que deseja sem problemas.
De qualquer forma, não há função padrão em C ++ para fazer o que você deseja. Você teria que fazer isso manualmente, e não seria trivial. Eu sugiro que você mantenha o caminho como está, não deve causar problemas.
É dependente de OS. Se você estiver usando o Linux, pode olhar RealPath (). Sem dúvida, o Windows tem algo comparável.
Afaik Não existe uma maneira padrão.
No entanto, você pode tentar esta abordagem (escrita em pseudocódigo):
string raw_dirname=get_directory_part(argv[1])
string basename=get_filename_part(argv[1])
string cwd=getcwd()
chdir(relative_dirname)
string absolute_dirname=getcwd()
chdir(cwd)
string absolute_filename=absulute_dirname + separator + basename
Mas note: não tenho certeza se há problemas quando os links simbólicos entram em jogo.