関数を書きたい:
inline char separator()
{
/* SOMETHING */
}
標準の C/C++/C++11 でシステムのファイル区切りを返す ? (システムによっては、スラッシュまたはバックスラッシュを意味します)。これを達成する方法はありますか?
関数を書きたい:
inline char separator()
{
/* SOMETHING */
}
標準の C/C++/C++11 でシステムのファイル区切りを返す ? (システムによっては、スラッシュまたはバックスラッシュを意味します)。これを達成する方法はありますか?
ifdefs をチェックする以外の方法がわかりません
inline char separator()
{
#ifdef _WIN32
return '\\';
#else
return '/';
#endif
}
または(PaperBirdMasterの提案による)
const char kPathSeparator =
#ifdef _WIN32
'\\';
#else
'/';
#endif
コンパイラが c++17 機能を提供している場合std::filesystem::path::preferred_separator
は、プラットフォームに応じて、優先される区切り文字を生成する which を使用できます。たとえば、Windows では通常\
、Linux では/
.
詳細については、これを参照してください。
この質問は、もっと厄介な問題を暗示しています。
UNIX と Winodws の違いだけに関心があり、ディレクトリとファイルだけに関心がある場合は、既に見たことが (ほとんど) うまくいきますが、パス名をその構成要素につなぎ合わせるというより一般的な問題は、はるかに厄介な問題です。プラットフォームによっては、パスに次の 1 つ以上が含まれる場合があります。
これにはサードパーティのライブラリ (さまざまな CPAN Perl モジュール、Boost など) があり、すべての OS にはこのためのシステム関数が含まれていますが、C には何も組み込まれておらず、C++ 標準はこの機能を (組み込むことによって) 獲得しただけです。ブースト モジュール) で 2017 年に。
そのような関数が処理する必要があるもののいくつかの例は次のとおりです。
他にもたくさんあります。
C++17 ファイルシステム ライブラリは、これらの可能性のすべてをカバーしていないことに注意してください。はstd::filesystem::path
、オプションのroot-name (ボリューム識別子)、オプションのroot-directory (絶対パスを識別するため)、およびディレクトリ セパレータで区切られた一連のファイル名で構成されます。これは、UNIX プラットフォームで有効である可能性が高いすべてのものと、他のプラットフォームのユースケースの大部分をカバーしていますが、包括的ではありません。たとえば、サブストリームのサポートはありません (OS に依存してファイル名にマップします。これは Mac OS X で行われますが、従来の MacOS では行われません)。また、ファイルのバージョン番号のサポートも含まれていません。
Pathおよび C++17 std::filesystem::pathクラスに関するウィキペディアのエントリも参照してください。
http://en.cppreference.com/w/cpp/filesystem
ディレクトリセパレーターで何をしたいのかを調べて(ベース名を抽出する、パスをディレクトリのリストに分割するなど)、それを行う関数を書くことをお勧めします。C++17 を使用している場合 (そして、コードが 17 より前の C++ コンパイラでコンパイルされないことが確実である場合)、(おそらく) 標準の C++ ライブラリ コードを使用して、この関数の移植可能な実装を作成できます。#ifdef
そうでない場合、その関数は、サポートする予定の各プラットフォームにプラットフォーム固有の を使用する必要があります。どの#error
条件も満たされない場合は、予期しないプラットフォームの条件を強制的に追加する必要があります。
または、許容できる場合は、これらすべての機能を含むサードパーティのライブラリ (Boost など) を使用します。
それはこのようなものになることができます
#if defined(WIN32) || defined(_WIN32)
#define PATH_SEPARATOR "\\"
#else
#define PATH_SEPARATOR "/"
#endif
受け入れられた回答は、Cygwin では機能しません。Windows で実行されている Cygwin コンパイル済みプログラムは、Windows スタイルの '\' セパレーターを使用できますが、_WIN32 などは定義しません。Cygwin で動作する修正されたソリューション:
inline char separator()
{
#if defined _WIN32 || defined __CYGWIN__
return '\\';
#else
return '/';
#endif
}
また
const char kPathSeparator =
#if defined _WIN32 || defined __CYGWIN__
'\\';
#else
'/';
#endif
誰も以下を提供していないことに驚いています。これは、他の人がここで提供しているものに少し基づいています。
この例では、使用のために実行されている実行可能ファイルの名前を動的に取得しようとしていますが、必要に応じてジャンプしてこれを再適用するのはそれほど難しくありません。
Windows では、スラッシュを使用して引数を示します。argv[0]
したがって、実行中のプログラムの名前を含む最初の引数で最初にそれを確認できます。
次の結果は、最後のスラッシュの前のパス名を削除sepd
し、プログラムのファイル名のままにすることに注意してください。
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[]){
//int a = 1
//int this = (a == 1) ? 20 : 30; //ternary operator
//is a==1 ? If yes then 'this' = 20, or else 'this' = 30
char *sepd = (strrchr(argv[0], '\/') != NULL) ?
strrchr(argv[0], '\/') :
strrchr(argv[0], '\\');
printf("%s\n\n", sepd);
printf("usage: .%s <host> \n\n", sepd);
while (getchar() != '\n');
}
しかし、実際には、これは非常に汚いものであり、Bash を組み込むという Windows の最新の動き (現時点ではまだ実装されていません) により、予期しない、または予期しない結果が生じる可能性があります。
また、特に#ifdef _WIN32
.