新石器Wiki

近年はシリコン(石)から進化した便利なもので溢れる時代。そんな気になった事や試した事など記す。

ユーザ用ツール

サイト用ツール


programing:linux-programing:file-splitpath-parse


差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
programing:linux-programing:file-splitpath-parse [2020/06/28 14:25] – [背景] yokoprograming:linux-programing:file-splitpath-parse [2020/07/01 10:48] (現在) – [コンパイル実行] yoko
行 3: 行 3:
 Linuxでパス文字列からディレクトリ名やファイル名を分割取得するのに、各要素を解析取得する関数を作ったので備忘録を残す。 Linuxでパス文字列からディレクトリ名やファイル名を分割取得するのに、各要素を解析取得する関数を作ったので備忘録を残す。
  
-背景+概要
 ---- ----
 Windowsでは、ファイルパスを分割するのに VC++では `_splitpath()`, Borland C++では `splitpath()` などの便利な関数が用意されている。   Windowsでは、ファイルパスを分割するのに VC++では `_splitpath()`, Borland C++では `splitpath()` などの便利な関数が用意されている。  
-Linuxではディレクトリ名やファイル名を取得する `dirname()` や `basename()` 関数が使えるが、所望する結果が得られなかったり、引数のパス領域が書き換えられたりする。そこで、文字列からファイル名要素を抽出する関数を作た。+Linuxではディレクトリ名やファイル名を取得する `dirname()` や `basename()` 関数が使えるが、どうも所望結果が得られなかったり、引数のパス領域が書き換えられたりする。そこで、文字列からファイル名要素を抽出する関数を作成。 
 + 
 +この関数の特徴は、入力し文字列を解析して各要素の開始ポインタ位置を戻す。又、戻り値でどの要素が存在してるかを知ることができる。入力した文字列は参照のみで非破壊なので、不要なコピー領域をmallocなどで確保しておかなくても必要な要素のみを抽出できる
  
 ファイル要素解析関数 ファイル要素解析関数
行 16: 行 18:
  * @file   _parsepath.h  * @file   _parsepath.h
  * @brief  Parse a file elements from a string function header.  * @brief  Parse a file elements from a string function header.
- * @date   2020/06/26+ * @author T.Yokobayashi de JR4QPV 
 + * @date   2020/06/28
  */  */
 #ifndef ___PARSEPATH_H__ #ifndef ___PARSEPATH_H__
行 26: 行 29:
 #define FLG_EXTENSION     (1) #define FLG_EXTENSION     (1)
 #define FLG_FILENAME      (2) #define FLG_FILENAME      (2)
-#define FLG_DIRECTORY     (4)+#define FLG_DIRNAME       (4)
 #define FLG_BASENAME      (8) #define FLG_BASENAME      (8)
 #define FLG_WILDCARDS     (0x10) #define FLG_WILDCARDS     (0x10)
行 49: 行 52:
  * History  * History
  * -------  * -------
- * - 2020/06/26 Created a sample code by JR4QPV.+ * - 2020/06/28 New created by JR4QPV.
  */  */
 </code> </code>
行 58: 行 61:
  * @file   _parsepath.c  * @file   _parsepath.c
  * @brief  Parse a file elements from a string.  * @brief  Parse a file elements from a string.
- * @date   2020/06/26+ * @author T.Yokobayashi de JR4QPV 
 + * @date   2020/07/01
  */  */
  
行 72: 行 76:
  * @param  extpos  拡張子名要素開始位置の格納先(NULL時は格納しない)  * @param  extpos  拡張子名要素開始位置の格納先(NULL時は格納しない)
  * @return 解析結果 =0:ファイル要素なし, ≠0:ファイル要素あり(要素フラグ)\n  * @return 解析結果 =0:ファイル要素なし, ≠0:ファイル要素あり(要素フラグ)\n
-         (FLG_DIRECTORY|FLG_BASENAME|FLG_FILENAME|FLG_EXTENSION|FLG_WILDCARDS)+         (FLG_DIRNAME|FLG_BASENAME|FLG_FILENAME|FLG_EXTENSION| \n 
 +          FLG_WILDCARDS|FLG_ABSPATH)
  * @details  * @details
   - pathの文字長が不正の時は「0」を返す。   - pathの文字長が不正の時は「0」を返す。
行 79: 行 84:
     各要素は、解析結果のポインタ位置から抽出する。     各要素は、解析結果のポインタ位置から抽出する。
   - 各要素は以下で抽出できる。\n   - 各要素は以下で抽出できる。\n
-     ディレクトリ名:*dirpos ~ *basepos (最後必ず'/') \n+     ディレクトリ名:*dirpos ~ *basepos (通常は'/'で終わる)\n
      ベース名:      *basepos 以降 \n      ベース名:      *basepos 以降 \n
      ファイル名:    *basepos ~ *extpos \n      ファイル名:    *basepos ~ *extpos \n
      拡張子:        *extpos 以降 ('.'で始まる)      拡張子:        *extpos 以降 ('.'で始まる)
 + *
 + * @note
 +  - "."と".."はディレクトリ名に判断し、この時は'/'で終わらない。
  * @attention  * @attention
- たぶん、マルチバイト文字には非対応。+  - マルチバイト文字には非対応。(UTF-8ならたぶん大丈夫)
  *****************************************************************************  *****************************************************************************
 */ */
行 102: 行 110:
  /* ディレクトリ名の有無チェック */  /* ディレクトリ名の有無チェック */
  if ((p = strrchr(path, '/')) != NULL) {  if ((p = strrchr(path, '/')) != NULL) {
- /* dir要素あり */+ /* dirname要素あり */
  bname = p+1;  bname = p+1;
- flg |= FLG_DIRECTORY;+ flg |= FLG_DIRNAME;
  
  /* 絶対パス名かチェック */  /* 絶対パス名かチェック */
  if (dname[0] == '/') /* '/'で始まるか ? */  if (dname[0] == '/') /* '/'で始まるか ? */
  flg |= FLG_ABSPATH;  flg |= FLG_ABSPATH;
 + }
 + else if ((strcmp(dname, ".") == 0) || (strcmp(dname, "..") == 0)) {
 + /* dirname要素あり */
 + n = strlen(dname);
 + bname = &dname[n];
 + flg |= FLG_DIRNAME;
  }  }
  
行 152: 行 166:
  * History  * History
  * -------  * -------
- * - 2020/06/26 Created a sample code by JR4QPV.+ * - 2020/06/28 New created by JR4QPV.
  */  */
 </code> </code>
- 
-本関数の特徴は、入力した文字列を解析して、各要素の開始ポインタ位置を戻す。又、戻り値でどの要素が存在してるかを知ることができる。又、入力した文字列は参照のみで非破壊なので、不要なコピー領域をmallocなどで確保しておかなくても必要な要素のみを抽出できる。 
  
 使い方 使い方
行 176: 行 188:
   int flg;   int flg;
      
 +  if (argc > 1)
 +    inpath = argv[1];
 +
   flg = _parsepath(inpath, &dname, &bname, NULL);   flg = _parsepath(inpath, &dname, &bname, NULL);
-  if (flg & FLG_DIRECTORY) {           /* dir要素あり ? */+  if (flg & FLG_DIRNAME) {             /* dirname要素あり ? */
     int n = bname - dname;             /* dir文字数(最後の'/'含む) */     int n = bname - dname;             /* dir文字数(最後の'/'含む) */
     strncpy(dir, dname, n);     strncpy(dir, dname, n);
     dir[n] = '\0';     dir[n] = '\0';
   }   }
-  else {                               /dir要素なし */+  else {                               /dirname要素なし */
     strcpy(dir, "");     strcpy(dir, "");
   }   }
      
-  if (flg & FLG_BASENAME) {            /* base要素あり ? */+  if (flg & FLG_BASENAME) {            /* basename要素あり ? */
     strcpy(base, bname);     strcpy(base, bname);
   }   }
-  else {                               /base要素なし */+  else {                               /basename要素なし */
     strcpy(base, "");     strcpy(base, "");
   }   }
行 207: 行 222:
 $ ./sample $ ./sample
 dir=/home/user/, base=test.txt dir=/home/user/, base=test.txt
 +
 +$ ./sample /aaa/bbb.ccc
 +dir=/aaa/, base=bbb.ccc
 </code> </code>
 +
 +  * カレントディレクトリのプログラムファイルを実行するには、「./」を付ける必要がある。
 +
 +
 +
 +GitHubから入手
 +------------
 +上記のソースファイルを「[[https://github.com/jr4qpv/parsepath|GitHub]]」に登録しているので、任意フォルダで下記コマンドでファイル一式を取得できる。
 +
 +<code bash>
 +$ git clone https://github.com/jr4qpv/parsepath
 +</code>
 +
 +関連記事
 +-------
 +
 +  - [[myblog>2020/06/29/linux-parsepath-splitpath/|【Linuxプログラム】パス文字列からディレクトリ名やファイル名を取得]]
 +
  
 参考 参考
programing/linux-programing/file-splitpath-parse.1593321920.txt.gz · 最終更新: 2020/06/28 14:25 by yoko