質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

1959閲覧

作成するファイルのパスを固定したい

asobinin

総合スコア69

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/12/23 21:30

編集2020/12/24 05:35

以下のプログラムを実行するとカレントディレクトリにconfig.jsonが作成されるのですが、どのディレクトリから実行されてもこのファイルの作成場所が実行ファイルと同じディレクトリになるようにしたいです。
どのような方法を取ればこれが実現できるのでしょうか。

追記:
私のやりたいことは上記の条件では足りませんでした。
PATHを通して使用することを想定していたため、実行ファイルの絶対パスを取得する必要がありました。

Cpp

1#include <fstream> 2 3int main() { 4 auto file = "config.json"; 5 std::ofstream ofs(file); 6 ofs << R"({"text": "あいうえお"})"; 7 ofs.close(); 8}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

実行ファイルのパスを取ってきて、そこにファイルを作るようにすればいいです
コマンドライン引数、args[0] に実行ファイルのパスがはいってます

投稿2020/12/23 22:21

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/12/23 22:28

それで得られるのは 絶対パス とは限らないのでは?
guest

0

解決しました。
OS依存なのはどうしようもないみたいですね。
filesystemの存在を忘れておりました、文字列加工などする必要がなかったです。

Cpp

1#include <iostream> 2#include <fstream> 3#include <filesystem> 4#include <string> 5 6namespace fs = std::filesystem; 7 8#ifdef WINDOWS 9 10#include <windows.h> 11 12auto get_exepath() { 13 char result[MAX_PATH]; 14 return std::string(result, GetModuleFileName(NULL, result, MAX_PATH)); 15} 16#else 17 18#include <limits.h> 19#include <unistd.h> 20 21auto get_exepath() { 22 char result[PATH_MAX]; 23 auto count = readlink("/proc/self/exe", result, PATH_MAX); 24 return std::string(result, (count > 0) ? count: 0); 25} 26#endif 27 28int main(int argc, char **argv) { 29 auto path = fs::absolute(get_exepath()).parent_path(); 30 path.append("config.json"); 31 std::cout << path << std::endl; 32 33 std::ofstream ofs(path); 34 ofs << R"({"text": "あいうえお"})"; 35 ofs.close(); 36} 37

投稿2020/12/24 05:32

asobinin

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

動作しました、ありがとうございました。
今回の場合は相対パスでも問題ありませんでした。
実行ファイルの文字列を取り除かないといけないのが少し面倒ですね。
今回はイテレータを使用していますが正規表現を用いるか迷いますね。

Cpp

1#include <fstream> 2#include <iostream> 3#include <string> 4 5template <class InputIter, class Predicate> 6constexpr auto skip_while( 7 InputIter first, InputIter last, 8 Predicate pred) { 9 while (first != last) { 10 if (!pred(*first)) break; 11 first++; 12 } 13 return first; 14} 15 16int main(int argc, char **argv) { 17 std::string a = argv[0]; 18 auto begin = skip_while(a.rbegin(), a.rend(), [](char c) {return c != '\'&& c != '/'; }); 19 auto path = std::string(begin, a.rend()); 20 std::reverse(path.begin(), path.end()); 21 path += "config.json"; 22 23 std::ofstream ofs(path); 24 ofs << R"({"text": "あいうえお"})"; 25 ofs.close(); 26}

投稿2020/12/24 00:10

編集2020/12/24 05:33
asobinin

総合スコア69

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/12/24 00:15

> 今回の場合は相対パスでも問題ありませんでした。 "今回の場合"とはどんな条件?
asobinin

2020/12/24 00:40

もしかしたら何か反例があるのかなと思い曖昧な表現をしてしまいました。 紛らわしい日本語を使用してしまい申し訳ありません。
episteme

2020/12/24 00:56

「実行ファイルはどこに置かれるかが分からないことを想定している」ので、 (相対パスではなく)絶対パスを手に入れたいんじゃなかったのか?
otn

2020/12/24 02:25

環境変数PATHをつかって探索されて起動された場合はこれでは駄目では? そういう起動をしないことが前提ならいいですが。
episteme

2020/12/24 02:27

↑ ソレが"今回の場合"か。
asobinin

2020/12/24 03:33

otn様のご指摘の通りPATHを用いた場合カレントディレクトリに作成されました。 PATHを通すことを想定していたので絶対パスでなければならないようです。 ありがとうございました。
episteme

2020/12/24 04:05

じゃ「今回の場合は相対パスでも問題ありませんでした」はウソか。
dodox86

2020/12/24 04:26 編集

>@質問者さん 結局やりたいことが実現できたのか、それとも一番やりたかったことは実現できなかったけど、次善の策で実現できたのか。それともいずれもできないので、回避する方法にしたのか、結局、問題は解決したのか。どうも分かりません。OSによって方法は異なり、ポータブルではありませんが、実行ファイル実行時の絶対PATHは取れないこともないです。Linuxであればprocファイルシステムの /proc/<プロセスID>/exe のシンボリックリンクにPATHがあります。
guest

0

ベストアンサー

実際に確認はしていませんが、下記に、サンプルコードが載っています。
プログラムが実行されているディレクトリ

投稿2020/12/23 23:17

akiruno-oneone

総合スコア815

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問