मुझे वह निर्देशिका कैसे मिल सकती है जिससे कोई प्रोग्राम चल रहा है?


269

क्या निर्देशिका का पूरा रास्ता प्राप्त करने के लिए एक मंच-अज्ञेय और फाइलसिस्टम-अज्ञेय विधि है जहां से कोई प्रोग्राम C / C ++ का उपयोग करके चल रहा है? वर्तमान कार्य निर्देशिका के साथ भ्रमित होने की नहीं। (कृपया लाइब्रेरी का सुझाव न दें जब तक कि वे मानक नहीं हैं जैसे कि क्लिब या एसटीएल।)

(यदि कोई प्लेटफ़ॉर्म / फाइलसिस्टम-एग्नॉस्टिक विधि नहीं है, तो विशिष्ट फाइल सिस्टम के लिए विंडोज और लिनक्स में काम करने वाले सुझावों का स्वागत है।)


@ अचरित: यह बहुत अच्छा होगा। (हालांकि यह मुद्दा आमतौर पर विंडोज के अंतर्गत नहीं आता है।)
अश्विन नानप्पा

2
जब तक आप मज़बूती से रास्ता नहीं निकाल सकते argv[0], तब तक तकनीक बहुत ही OS पर निर्भर रहने वाली है।
डेविड आर ट्रिब्बल

1
बस स्पष्ट करने के लिए: 'वर्तमान निर्देशिका', या, 'जिस निर्देशिका से कार्यक्रम चल रहा है' (प्रश्न की शब्दावली में) वह निर्देशिका है जहां कार्यक्रम की छवि फ़ाइल (~ .exe फ़ाइल) स्थित है, और 'वर्तमान कार्यशील निर्देशिका' वह निर्देशिका है, जो प्रोग्राम के सापेक्ष पथों का उपयोग करने पर स्वतः पूर्ण हो जाती है?
colemik

3
जब आप #include <windows.h>, Windows स्वचालित रूप char*से निष्पादन योग्य पथ में डालता है _pgmptr। यदि आप केवल विंडोज पर काम कर रहे हैं तो आपको अतिरिक्त कार्यों को कॉल करने या कबाड़ को संभालने की आवश्यकता नहीं है।
rsethc

1
हालांकि टिप्पणी तीन साल पहले की है, मैं rsethc की टिप्पणी के बारे में विस्तार करना चाहूंगा _pgmptr। MSDN दस्तावेज़ीकरण बताता है कि _pgmptrऔर _wpgmptrचर को हटा दिया गया है, और आपको फ़ंक्शन _get_pgmptr(char**)या _get_wpgmptr(wchar_t**)इसके बजाय का उपयोग करना चाहिए । एमएसडीएन
हाइड्रिक्सिक्स

जवाबों:


181

यहां कोडिंग एप्लिकेशन को पूर्ण पथ प्राप्त करने के लिए कोड है:

खिड़कियाँ:

int bytes = GetModuleFileName(NULL, pBuf, len);
return bytes ? bytes : -1;

लिनक्स:

int bytes = MIN(readlink("/proc/self/exe", pBuf, len), len - 1);
if(bytes >= 0)
    pBuf[bytes] = '\0';
return bytes;

3
मुझे लगता है कि यह एकमात्र ऐसा उत्तर है जो प्रश्न का उत्तर देता है, और विंडोज और लिनक्स दोनों के लिए ऐसा करता है। अच्छी नौकरी।
फ्रैंक स्ज़बेकटा

6
Boo for / proc / pid / exe - किसी कारण से OS X पर समर्थित नहीं है।
क्रिस लुत्ज़

24
जब मैं कोड देखता /procहूं जो मेरे हिस्से में दिखता है तो थोड़ा मर जाता है। सारी दुनिया लिनक्स नहीं है, और उस पर भी एक मंच /procको संस्करण से संस्करण में बदलने के अधीन माना जाना चाहिए, आर्क से आर्क, आदि
asveikau

4
यदि वे लिनक्स पर अलियासिड कमांड का उपयोग करते हुए लॉन्च करते हैं, तो argv [0] "कमांड का नाम" या विस्तारित है?
एंडी डेंट

20
कैसे के बारे char pBuf[256]; size_t len = sizeof(pBuf);में समाधान स्पष्ट रूप से बताने के लिए जोड़ें ।
charles.cc.hsu

166

यदि आप अपना कार्यक्रम पहली बार शुरू करते हैं, तो आप वर्तमान निर्देशिका प्राप्त करते हैं, तो आपके पास वह निर्देशिका है जिससे आपका कार्यक्रम शुरू किया गया था। किसी वैरिएबल में वैल्यू स्टोर करें और इसे बाद में अपने प्रोग्राम में देखें। यह उस निर्देशिका से अलग है जो वर्तमान निष्पादन योग्य प्रोग्राम फ़ाइल रखती है । यह जरूरी नहीं कि एक ही निर्देशिका हो; यदि कोई प्रोग्राम को कमांड प्रॉम्प्ट से चलाता है, तो प्रोग्राम प्रॉम्प्ट के वर्तमान वर्किंग डायरेक्टरी से चलाया जा रहा है , भले ही प्रोग्राम फाइल कहीं और रहता हो।

getcwd एक POSIX फ़ंक्शन है और सभी POSIX अनुरूप प्लेटफार्मों द्वारा बॉक्स से बाहर समर्थित है। आपको कुछ विशेष नहीं करना होगा (इसके अलावा सही हेडर्स को अनइंस्टॉल करने के अलावा। यूनिक्स पर और विंडोज के लिए डायरेक्ट करें।)।

चूंकि आप एक C प्रोग्राम बना रहे हैं, यह डिफ़ॉल्ट c रन टाइम लाइब्रेरी के साथ लिंक होगा जो सिस्टम में सभी प्रक्रियाओं से जुड़ा हुआ है (विशेष रूप से तैयार किए गए अपवादों से बचा जाता है) और यह डिफ़ॉल्ट रूप से इस फ़ंक्शन को शामिल करेगा। सीआरटी को कभी भी बाहरी पुस्तकालय नहीं माना जाता है क्योंकि यह ओएस को बुनियादी मानक अनुरूप इंटरफेस प्रदान करता है।

विंडोज़ पर getcwd फ़ंक्शन को _getcwd के पक्ष में चित्रित किया गया है। मुझे लगता है कि आप इसे इस अंदाज में इस्तेमाल कर सकते हैं।

#include <stdio.h>  /* defines FILENAME_MAX */
#ifdef WINDOWS
    #include <direct.h>
    #define GetCurrentDir _getcwd
#else
    #include <unistd.h>
    #define GetCurrentDir getcwd
 #endif

 char cCurrentPath[FILENAME_MAX];

 if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
     {
     return errno;
     }

cCurrentPath[sizeof(cCurrentPath) - 1] = '\0'; /* not really required */

printf ("The current working directory is %s", cCurrentPath);

44
अच्छा जवाब, लेकिन मुझे लगा कि "वर्तमान कामकाजी निर्देशिका" वह नहीं थी जो वह चाहता था।
माइकल बूर

4
आपको यह जोड़ना चाहिए कि भले ही कुछ दस्तावेज़ों में कहा गया हो कि cCurrentpath को शून्य किया जा सकता है और getcwd द्वारा आवंटित किया जाएगा getcwd मैक ओएस पर कुछ आवंटित नहीं करता है और चुपचाप आपके प्रोग्राम को क्रैश कर देता है
Janusz

4
एक छोटी सी त्रुटि है, लेकिन दुर्भाग्य से मैं अभी तक संपादित नहीं कर सकता .. लाइन 10: cCurrentpath: cCurrentPath होना चाहिए
Lipis

8
विंडोज पर IMO POSIXy नाम वाले फंक्शंस (जिनमें से कुछ अंडरस्कोर से शुरू होते हैं) को आम तौर पर टाला जाना चाहिए। वे असली Windows API नहीं हैं, बल्कि CRT हैं। आप जिस Windows API का उपयोग करना चाहते हैं, वह GetCurrentDirectory () है। msdn.microsoft.com/en-us/library/aa364934(VS.85).aspx
asveikau

6
माइक का जवाब सही है। "वर्तमान निर्देशिका" हमेशा उस निर्देशिका के समान नहीं होती है जिस तरह से बाइनरी चल रही है। उदाहरण के लिए, यदि कोई ऐप विंडोज पर सेवा के रूप में चलता है, तो वर्तमान निर्देशिका संभवतः C: \ Windows \ System32 होगी, जबकि बाइनरी डायर अलग है।
लकी ल्यूक

42

यह cplusplus फोरम से है

खिड़कियों पर:

#include <string>
#include <windows.h>

std::string getexepath()
{
  char result[ MAX_PATH ];
  return std::string( result, GetModuleFileName( NULL, result, MAX_PATH ) );
}

लिनक्स पर:

#include <string>
#include <limits.h>
#include <unistd.h>

std::string getexepath()
{
  char result[ PATH_MAX ];
  ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
  return std::string( result, (count > 0) ? count : 0 );
}

HP-UX पर:

#include <string>
#include <limits.h>
#define _PSTAT64
#include <sys/pstat.h>
#include <sys/types.h>
#include <unistd.h>

std::string getexepath()
{
  char result[ PATH_MAX ];
  struct pst_status ps;

  if (pstat_getproc( &ps, sizeof( ps ), 0, getpid() ) < 0)
    return std::string();

  if (pstat_getpathname( result, PATH_MAX, &ps.pst_fid_text ) < 0)
    return std::string();

  return std::string( result );
}

1
वह Windows समाधान पथ में गैर-ANSI वर्णों को हैंडल नहीं करेगा। आपको शायद GetModuleFileNameW का उपयोग करना चाहिए और इसे स्पष्ट रूप से UTF-8 में परिवर्तित करना चाहिए (जब भी आपको एक फाइलसिस्टम कमांड जारी करने की आवश्यकता हो तो इसे वापस कन्वर्ट करने के लिए सावधान रहें)।
एड्रियन मैक्कार्थी

3
विंडोज समाधान के लिए, मुझे error: cannot convert 'char*' to 'LPWCH {aka wchar_t*}' for argument '2' to 'DWORD GetModuleFileNameW(HMODULE, LPWCH, DWORD)'मिनगडब्ल्यू के साथ संकलन करते समय त्रुटि मिलती है ।
हैलोगूडीबाई

2
@ एड्रियन, इम आम तौर पर एक विंडोज़ प्रोग्रामर नहीं है, लेकिन स्वचालित रूप से कार्यों के _W () स्वाद का उपयोग करने के लिए अपने संकलक को बताने के लिए कोई DEFINE या कोई व्यक्ति नहीं है?
ऑक्टोपस

1
@ ऑक्टोपस: विस्तृत कॉल का उपयोग करने के लिए, आपको WCHAR (char के बजाय) और std :: wstring (std के बजाय :: string) का उपयोग करने की आवश्यकता होगी।
एड्रियन मैक्कार्थी

29

यदि आप पुस्तकालयों के बिना एक मानक तरीका चाहते हैं: नहीं। एक निर्देशिका की पूरी अवधारणा मानक में शामिल नहीं है।

यदि आप इस बात से सहमत हैं कि निकट-मानक लीब पर कुछ (पोर्टेबल) निर्भरता ठीक है: बूस्ट की फाइल सिस्टम लाइब्रेरी का उपयोग करें और शुरुआती_पथ () के लिए पूछें ।

IMHO जो आपके करीबी के साथ हो सकता है, अच्छे कर्म के साथ (बूस्ट एक अच्छी तरह से स्थापित उच्च गुणवत्ता वाला पुस्तकालय है)


8
बूस्ट डॉक्स से: टेम्पलेट <क्लास पाथ> कांस्ट पाथ और इनिशियल_पैथ (); रिटर्न: मुख्य में प्रवेश के समय current_path ()। और current_path () 'के रूप में यदि POSIX getcwd ()' है। यह वह नहीं है जो प्रश्नकर्ता ने अनुरोध किया है।
जोनाथन लेफलर

बूस्ट देखें। http:// doc
libs/

जैसा कि टिप्पणी की गई है, यह वह मार्ग देता है जहां से बाइनरी को आमंत्रित किया गया था, बाइनरी को पथ नहीं ... जैसा कि इसे एक अलग फ़ोल्डर से शुरू किया जा सकता है।
jpo38

21

फाइलसिस्टम टीएस अब एक मानक है (और gcc 5.3+ और क्लैग 3.9+ द्वारा समर्थित है), इसलिए आप current_path()इससे फ़ंक्शन का उपयोग कर सकते हैं :

std::string path = std::experimental::filesystem::current_path();

फाइलसिस्टम को शामिल करने के लिए gcc (5.3+) में आपको उपयोग करने की आवश्यकता है:

#include <experimental/filesystem>

और अपने कोड को -lstdc++fsध्वज के साथ लिंक करें ।

यदि आप Microsoft Visual Studio के साथ फाइलसिस्टम का उपयोग करना चाहते हैं, तो इसे पढ़ें


6
1-2) Returns the absolute path of the current working directory, obtained as if by POSIX getcwd. (2) returns path() if error occurs. संदर्भित लिंक से, डाउनवोट किया गया है, क्योंकि ओपी विशेष रूप से वर्तमान कार्यशील निर्देशिका के बजाय निष्पादन योग्य के वर्तमान पथ के बारे में पूछता है।
एस। साद

20

मुझे पता है कि इस एक जवाब को फेंकने के लिए दिन में बहुत देर हो चुकी है, लेकिन मैंने पाया कि कोई भी उत्तर मेरे लिए अपने स्वयं के समाधान के रूप में उपयोगी नहीं था। आपके CWD से आपके बिन फ़ोल्डर तक का रास्ता पाने का एक बहुत ही सरल तरीका है:

int main(int argc, char* argv[])
{
    std::string argv_str(argv[0]);
    std::string base = argv_str.substr(0, argv_str.find_last_of("/"));
}

अब आप इसे अपने रिश्तेदार पथ के लिए एक आधार के रूप में उपयोग कर सकते हैं। इसलिए उदाहरण के लिए मेरे पास यह निर्देशिका संरचना है:

main
  ----> test
  ----> src
  ----> bin

और मैं अपने स्रोत कोड को बिन में संकलित करना चाहता हूं और परीक्षण के लिए एक लॉग लिख सकता हूं मैं बस इस कोड को अपने कोड में जोड़ सकता हूं।

std::string pathToWrite = base + "/../test/test.log";

मैंने पूर्ण पथ, उपनाम आदि का उपयोग करके लिनक्स पर इस दृष्टिकोण की कोशिश की है और यह ठीक काम करता है।

ध्यान दें:

यदि आप खिड़कियों पर हैं, तो आपको फ़ाइल विभाजक नहीं '/' के रूप में '\' का उपयोग करना चाहिए। उदाहरण के लिए आपको इससे बचना होगा:

std::string base = argv[0].substr(0, argv[0].find_last_of("\\"));

मुझे लगता है कि यह काम करना चाहिए, लेकिन परीक्षण नहीं किया गया है, इसलिए टिप्पणी की सराहना की जाएगी अगर यह काम करता है या नहीं तो ठीक है।


हां, यह विंडोज पर भी काम करता है। मुझे लगता है कि यह सबसे अच्छा समाधान है। जहाँ तक मुझे पता है कि argv [0] हमेशा निष्पादन योग्य के लिए रास्ता रखता है।
वोडज़ु

4
argv[0]एक बहुत अच्छा विचार है, लेकिन दुर्भाग्य से जो मुझे लिनक्स पर मिल रहा है वह है "./my_executable__" या "./make/my_executable_name"। मूल रूप से मुझे जो मिलता है वह पूरी तरह से निर्भर करता है कि मैं इसे कैसे लॉन्च करता हूं
Xeverous

@Xeverous: तो क्या? अगर मेरे पास मेरे निष्पादन योग्य के सापेक्ष कुछ फाइलें हैं, जिन्हें खोलने की जरूरत है, तो आपके मामलों में "./" या "./make/" से काम करना चाहिए। "।" वर्तमान कार्यशील निर्देशिका है, और argv [0] आपको वहां से निष्पादन योग्य के लिए सापेक्ष रास्ता बताएगा, जो कि ओपी को चाहिए। यह किसी भी मामले में वही है जो मुझे चाहिए।
नीलो

9

नहीं, कोई मानक तरीका नहीं है। मेरा मानना ​​है कि सी / सी ++ मानक निर्देशिका (या अन्य फाइल सिस्टम संगठनों) के अस्तित्व पर भी विचार नहीं करते हैं।

Windows पर GetModuleFileName () hModule पैरामीटर NULL पर सेट होने पर, वर्तमान प्रक्रिया की निष्पादन योग्य फ़ाइल पर पूर्ण पथ लौटा देगा । मैं लिनक्स के साथ मदद नहीं कर सकता।

इसके अलावा, आपको स्पष्ट करना चाहिए कि क्या आप वर्तमान निर्देशिका या निर्देशिका चाहते हैं जो प्रोग्राम छवि / निष्पादन योग्य रहता है। जैसा कि यह खड़ा है आपका सवाल इस बिंदु पर थोड़ा अस्पष्ट है।


9

विंडोज़ पर सबसे सरल तरीका _get_pgmptrफ़ंक्शन stdlib.hको एक स्ट्रिंग को पॉइंटर प्राप्त करने के लिए उपयोग करना है जो निष्पादन योग्य नाम सहित पूर्ण निष्पादन योग्य पथ का प्रतिनिधित्व करता है।

char* path;
_get_pgmptr(&path);
printf(path); // Example output: C:/Projects/Hello/World.exe

8

हो सकता है कि argv [0] के साथ वर्तमान कामकाजी निर्देशिका को संक्षिप्त करें? मुझे यकीन नहीं है कि अगर यह विंडोज में काम करेगा लेकिन यह लिनक्स में काम करता है।

उदाहरण के लिए:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv) {
    char the_path[256];

    getcwd(the_path, 255);
    strcat(the_path, "/");
    strcat(the_path, argv[0]);

    printf("%s\n", the_path);

    return 0;
}

जब चलाते हैं, तो यह आउटपुट:

jeremy @ jeremy-desktop: ~ / Desktop $ ./est /home/jeremy/Desktop//
test


आपको यह देखने के लिए चेक की आवश्यकता होगी कि क्या कोई पूर्ण पथ argv में दिया गया है [को ०]। लेकिन इससे भी महत्वपूर्ण बात यह है कि अगर PATH के माध्यम से छवि स्थित है तो क्या होगा? क्या लिनक्स पूरा रास्ता भरता है या सिर्फ कमांड लाइन पर क्या है?
माइकल बूर

जैसा कि माइक बी ने बताया, यह एक गैर-सामान्य समाधान है; यह केवल कुछ बहुत ही सीमित परिस्थितियों में काम करता है। मूल रूप से, केवल जब आप एक संबंधित पथनाम द्वारा कमांड चलाते हैं - और जब आप चलाते हैं तो यह सब कुछ सुरुचिपूर्ण नहीं होता है ..////bin/progname के बजाय ./test
जोनाथन

यदि आप वर्तमान निर्देशिका की तुलना में argv [0] के संभावित सापेक्ष पथ को हल करते हैं (क्योंकि argv [0] "../../myprogram.exe") हो सकता है, तो शायद यह सवाल का जवाब देने का सबसे सुरक्षित तरीका है। यह हमेशा काम करेगा और पोर्टेबल है (यह एंड्रॉइड पर भी काम करता है!)।
jpo38

7

Win32 के लिए GetCurrentDirectory को ट्रिक करना चाहिए।


नहीं है इस समारोह के साथ बड़ी पकड़ : थ्रेड अनुप्रयोगों और साझा लाइब्रेरी कोड GetCurrentDirectory समारोह उपयोग नहीं करना चाहिए और रिश्तेदार pathnames का उपयोग कर से बचना चाहिए । यदि आप इस धारणा के साथ काम कर सकते हैं तो यह सबसे अच्छा समाधान है।
मैक्लेरी

6

आप उस उद्देश्य के लिए argv [0] का उपयोग नहीं कर सकते हैं, आमतौर पर इसमें निष्पादन योग्य के लिए पूर्ण पथ शामिल होता है, लेकिन शून्य रूप से नहीं - क्षेत्र में मनमाने मूल्य के साथ प्रक्रिया बनाई जा सकती है।

यह भी ध्यान रखें, वर्तमान निर्देशिका और निष्पादन योग्य के साथ निर्देशिका दो अलग-अलग चीजें हैं, इसलिए getcwd () आपकी मदद नहीं करेगा।

Windows पर GetModuleFileName (), लिनक्स पर / देव / proc / procID / .. फ़ाइलों का उपयोग करें।


3

बस यहाँ पर ढेर करने के लिए ...

कोई मानक समाधान नहीं है, क्योंकि भाषाएं अंतर्निहित फ़ाइल सिस्टम के अज्ञेय हैं, इसलिए जैसा कि अन्य ने कहा है, एक निर्देशिका आधारित फ़ाइल सिस्टम की अवधारणा c / c ++ भाषाओं के दायरे से बाहर है।

उसके शीर्ष पर, आप वर्तमान कार्य निर्देशिका नहीं चाहते हैं, लेकिन कार्यक्रम जिस निर्देशिका में चल रहा है, उसे इस बात पर ध्यान देना चाहिए कि प्रोग्राम को यह कहाँ तक मिला है - यानी यह कांटा के माध्यम से एक नई प्रक्रिया के रूप में पैदा किया गया था, आदि। निर्देशिका प्राप्त करने के लिए एक प्रोग्राम चल रहा है, जैसा कि समाधानों ने प्रदर्शित किया है, इसके लिए आवश्यक है कि आप उस प्रश्न की ऑपरेटिंग सिस्टम की प्रक्रिया नियंत्रण संरचनाओं से जानकारी प्राप्त करें, जो इस प्रश्न पर एकमात्र प्राधिकरण है। इस प्रकार, परिभाषा के अनुसार, इसका ओएस विशिष्ट समाधान है।


3

कंसोल पर विंडोज सिस्टम के लिए आप सिस्टम ( dir) कमांड का उपयोग कर सकते हैं । और सांत्वना आप निर्देशिका और आदि पढ़ें के बारे में के बारे में जानकारी देता है dirपर आदेश cmd। लेकिन यूनिक्स जैसी प्रणालियों के लिए, मुझे नहीं पता ... यदि यह कमांड चलाया जाता है, तो बैश कमांड पढ़ें। lsनिर्देशिका प्रदर्शित नहीं करता है ...

उदाहरण:

int main()
{
    system("dir");
    system("pause"); //this wait for Enter-key-press;
    return 0;
}

2
#include <windows.h>
using namespace std;

// The directory path returned by native GetCurrentDirectory() no end backslash
string getCurrentDirectoryOnWindows()
{
    const unsigned long maxDir = 260;
    char currentDir[maxDir];
    GetCurrentDirectory(maxDir, currentDir);
    return string(currentDir);
}

1

POSIX प्लेटफार्मों पर, आप getcwd () का उपयोग कर सकते हैं ।

Windows पर, आप उपयोग कर सकते हैं _getcwd () , के उपयोग के रूप getcwd () का उपयोग पदावनत कर दिया गया है।

मानक पुस्तकालयों के लिए, यदि बूस्ट आपके लिए पर्याप्त मानक थे, तो मैंने Boost :: filesystem का सुझाव दिया होगा, लेकिन वे प्रस्ताव से पथ सामान्यीकरण को हटा दिया है। TR2 पूरी तरह से मानक समाधान के लिए आसानी से उपलब्ध होने तक आपको इंतजार करना पड़ सकता है ।


10
getcwd () वह नहीं करता जो प्रश्नकर्ता ने पूछा था।
जोनाथन लेफलर

क्या यह नहीं है कि स्वीकृत उत्तर गेटवेड () का उपयोग करता है, या क्या मैं सिर्फ समझ नहीं रहा हूं?
संवतोमिशी

मैंने उत्थान किया क्योंकि आप वही हैं जो सबसे पहले सही उत्तर के रूप में माना जाता है।
अरनौद

यह उत्तर प्रश्न को संबोधित करने का प्रयास भी नहीं करता है। इसे लिखने पर शर्म आती है।
हैलोवर्ल्ड

1

रिश्तेदार रास्तों के लिए, यहाँ मैंने क्या किया। मुझे इस प्रश्न की आयु के बारे में पता है, मैं बस एक सरल उत्तर देना चाहता हूं जो अधिकांश मामलों में काम करता है:

कहो आपके पास एक रास्ता है:

"path/to/file/folder"

किसी कारण के लिए, ग्रहण में बने लिनक्स-निर्मित निष्पादनयोग्य इसके साथ ठीक काम करते हैं। हालाँकि, अगर काम करने के लिए इस तरह से एक रास्ता दिया जाता है तो खिड़कियां बहुत भ्रमित हो जाती हैं!

जैसा कि ऊपर कहा गया है कि निष्पादन योग्य वर्तमान मार्ग प्राप्त करने के कई तरीके हैं, लेकिन मुझे सबसे आसान तरीका काम के मामलों में एक आकर्षण लगता है जो इसे आपके मार्ग के सामने जोड़ रहा है:

"./path/to/file/folder"

बस "./" जोड़ना आपको क्रमबद्ध करना चाहिए! :) फिर आप अपनी इच्छानुसार जो भी डायरेक्टरी चाहे लोड करना शुरू कर सकते हैं, जब तक कि यह एक्जीक्यूटेबल के साथ ही है।

संपादित करें: यह काम नहीं करेगा यदि आप कोड से निष्पादन योग्य को लॉन्च करने का प्रयास करते हैं :: ब्लॉक यदि वह विकास पर्यावरण का उपयोग कर रहा है, तो किसी कारण से, कोड :: ब्लॉक सामान को सही लोड नहीं करता है ...: डी

EDIT2: कुछ नई चीज़ें जो मैंने पाई हैं, वह यह है कि यदि आप अपने कोड में इस तरह एक स्थिर पथ निर्दिष्ट करते हैं (उदाहरण के लिए मान लें। कुछ ऐसा है जिसे आपको लोड करने की आवश्यकता है):

"resources/Example.data"

यदि आप अपने ऐप को वास्तविक निर्देशिका से लॉन्च करते हैं (या विंडोज में, आप एक शॉर्टकट बनाते हैं, और अपने ऐप को काम करने वाले डायर को सेट करते हैं) तो यह उसी तरह काम करेगा। लापता संसाधन / फ़ाइल पथ से संबंधित समस्याओं को डीबग करते समय इसे ध्यान में रखें। (विशेष रूप से आईडीई में, जो आईडीई से बिल्ड एक्स को लॉन्च करते समय गलत काम करने वाले डायर को सेट करता है)


1

एक पुस्तकालय समाधान (हालांकि मुझे पता है कि यह नहीं पूछा गया था)। यदि आप Qt का उपयोग करते हैं: QCoreApplication::applicationDirPath()


1

बस मेरे दो सेंट, लेकिन निम्न कोड सी +१, में आंशिक रूप से काम नहीं करता है?

#include <iostream>
#include <filesystem>
namespace fs = std::filesystem;

int main(int argc, char* argv[])
{
    std::cout << "Path is " << fs::path(argv[0]).parent_path() << '\n';
}

कम से कम लिनक्स पर मेरे लिए काम करने लगता है।

पिछले विचार के आधार पर, मेरे पास अब है:

std::filesystem::path prepend_exe_path(const std::string& filename, const std::string& exe_path = "");

कार्यान्वयन के साथ:

fs::path prepend_exe_path(const std::string& filename, const std::string& exe_path)
{
    static auto exe_parent_path = fs::path(exe_path).parent_path();
    return exe_parent_path / filename;
}

और प्रारंभिक चाल में main():

(void) prepend_exe_path("", argv[0]);

Argv [0] विचार के लिए @Sam Redway को धन्यवाद। और हां, मैं समझता हूं कि जब ओपी ने सवाल पूछा तो सी ++ 17 कई सालों तक आसपास नहीं था।


0

बूस्ट फाइलसिस्टम initial_path()पॉसिक्स की तरह व्यवहार करता है getcwd(), और न ही आप जो चाहते हैं वह खुद ही करता है, लेकिन एपेंडिंगargv[0] दोनों में से किसी को भी इसे करना चाहिए।

आप ध्यान दें कि परिणाम हमेशा सुंदर नहीं होता है - आपको कुछ चीजें मिल सकती हैं जैसे /foo/bar/../../baz/a.outया/foo/bar//baz/a.out , लेकिन मेरा मानना ​​है कि यह हमेशा एक वैध पथ में परिणाम देता है जो निष्पादन योग्य नाम देता है (ध्यान दें कि एक पथ में लगातार स्लैश एक के लिए ढह गए हैं)।

मैंने पहले एक समाधान लिखा था envp(तीसरा तर्क main()जिसमें लिनक्स पर काम किया गया था, लेकिन विंडोज पर काम करने योग्य नहीं था, इसलिए मैं अनिवार्य रूप से उसी समाधान की सिफारिश कर रहा हूं जैसा कि किसी और ने पहले किया था, लेकिन अतिरिक्त स्पष्टीकरण के साथ यह वास्तव में सही क्यों है भले ही परिणाम सुंदर नहीं हैं।


0

मिनोक के रूप में ने उल्लेख किया है, सी मानक या सी ++ मानक निर्दिष्ट ऐसी कोई कार्यक्षमता नहीं है। यह विशुद्ध रूप से ओएस-विशिष्ट विशेषता माना जाता है और यह POSIX मानक में निर्दिष्ट है, उदाहरण के लिए।

Thorsten79 ने अच्छा सुझाव दिया है, यह Boost.Filesystem पुस्तकालय है। हालाँकि, यदि आप अपने प्रोग्राम के लिए बाइनरी फॉर्म में कोई लिंक-टाइम निर्भरता नहीं रखना चाहते हैं तो यह असुविधाजनक हो सकता है।

एक अच्छा विकल्प मैं सुझाऊंगा कि 100% हेडर-केवल STLSoft C ++ लाइब्रेरीज़ मैथ्यू विल्सन का संग्रह है (C ++ के बारे में पुस्तकों को अवश्य पढ़ें)। पोर्टेबल मुखौटा है प्लेटफ़ॉर्मएलएल सिस्टम-विशिष्ट एपीआई तक पहुंच प्रदान करता है: विंडोज के लिए WinSTL और यूनिक्स पर UnixSTL, इसलिए यह पोर्टेबल समाधान है। सभी सिस्टम-विशिष्ट तत्व लक्षण और नीतियों के उपयोग के साथ निर्दिष्ट हैं, इसलिए यह एक्स्टेंसिबल फ्रेमवर्क है। निश्चित रूप से प्रदान की गई फाइलसिस्टम लाइब्रेरी है।


0

Linux bash कमांड जो प्रोगनेम है प्रोग्राम की राह ।

यहां तक ​​कि अगर कोई आपके प्रोग्राम के भीतर से कौन सी कमांड जारी कर सकता है और आउटपुट को एक tmp फ़ाइल में निर्देशित कर सकता है और प्रोग्राम बाद में उस tmp फ़ाइल को पढ़ता है, तो यह आपको यह नहीं बताएगा कि क्या वह प्रोग्राम एक निष्पादन है। यह केवल आपको बताता है कि उस नाम का कोई कार्यक्रम कहां स्थित है।

क्या आवश्यक है अपनी प्रक्रिया आईडी संख्या प्राप्त करने के लिए, और नाम के लिए पथ को पार्स करने के लिए

मेरे कार्यक्रम में मैं यह जानना चाहता हूं कि क्या प्रोग्राम उपयोगकर्ता की बिन निर्देशिका से या किसी अन्य से पथ में या usr / bin से निष्पादित किया गया था। / usr / bin में समर्थित संस्करण होगा। मेरी भावना यह है कि लिनक्स में एक समाधान है जो पोर्टेबल है।



0

प्रयोगात्मक फाइलसिस्टम का उपयोग करके C ++ 11 से शुरू होता है, और C ++ 14-C ++ 17 के साथ-साथ आधिकारिक फाइलसिस्टम का उपयोग करता है।

application.h:

#pragma once

//
// https://en.cppreference.com/w/User:D41D8CD98F/feature_testing_macros
//
#ifdef __cpp_lib_filesystem
#include <filesystem>
#else
#include <experimental/filesystem>

namespace std {
    namespace filesystem = experimental::filesystem;
}
#endif

std::filesystem::path getexepath();

application.cpp:

#include "application.h"
#ifdef _WIN32
#include <windows.h>    //GetModuleFileNameW
#else
#include <limits.h>
#include <unistd.h>     //readlink
#endif

std::filesystem::path getexepath()
{
#ifdef _WIN32
    wchar_t path[MAX_PATH] = { 0 };
    GetModuleFileNameW(NULL, path, MAX_PATH);
    return path;
#else
    char result[PATH_MAX];
    ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
    return std::string(result, (count > 0) ? count : 0);
#endif
}

अच्छा जवाब है, लेकिन नाम स्थान की घोषणाओं या परिभाषाओं को जोड़ना अपरिभाषित व्यवहार हैstd । इससे बचने के लिए, आप दोनों नामस्थान std::filesystemऔर std::experimental::filesystemअपनी पसंद के तीसरे नामस्थान में जोड़ सकते हैं , या बस उपयोग कर सकते हैं using std::filesystem::path, अगर आपको pathवैश्विक नामस्थान की घोषणा को जोड़ने में कोई आपत्ति नहीं है ।
कैसियो रेनन

मुझे लगता है कि C ++ 14 के बाद प्रायोगिक :: फाइलसिस्टम का उपयोग नहीं किया जाता है, इसलिए आप इस बारे में भूल सकते हैं? (पहली #if शाखा में जाता है)
TarmoPikaro
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.