একটি প্রোগ্রাম যে ডিরেক্টরি থেকে চলছে তা আমি কীভাবে পাব?


269

সি / সি ++ ব্যবহার করে যে প্রোগ্রামটি চলছে সেখানকার ডিরেক্টরিটির পুরো পথটি অর্জন করার জন্য কি প্ল্যাটফর্ম-অজোনস্টিক এবং ফাইলসিসটম-অগ্নিস্টিক পদ্ধতি রয়েছে? বর্তমান ওয়ার্কিং ডিরেক্টরিটি নিয়ে বিভ্রান্ত হওয়ার দরকার নেই। (দয়া করে লাইব্রেরিগুলি ক্লাইব বা এসটিএল-এর মতো স্ট্যান্ডার্ড না হলে প্রস্তাব করবেন না))

(যদি প্ল্যাটফর্ম / ফাইলসিসটম-অজোনস্টিক পদ্ধতি না থাকে তবে নির্দিষ্ট ফাইল সিস্টেমগুলির জন্য উইন্ডোজ এবং লিনাক্সে কাজ করা পরামর্শগুলিও স্বাগত।


@ চাচার্ট: এটি দুর্দান্ত হবে। (যদিও এই সমস্যাটি সাধারণত উইন্ডোজের আওতায় আসে না))
আশ্বিন নানজাপ্পা

2
আপনি নির্ভরযোগ্যভাবে থেকে পথটি বের argv[0]করতে না পারলে কৌশলটি খুব ওএস-নির্ভর হয়ে উঠবে।
ডেভিড আর ট্রিবিলে

1
কেবলমাত্র স্পষ্ট করার জন্য: 'বর্তমান ডিরেক্টরি', বা 'প্রোগ্রামটি যে ডিরেক্টরি থেকে প্রোগ্রামটি চালাচ্ছে' তা (প্রশ্নের পরিভাষায়) হ'ল ডিরেক্টরিটি যেখানে প্রোগ্রামের চিত্র ফাইল ((.exe ফাইল) অবস্থিত, এবং 'বর্তমান ওয়ার্কিং ডিরেক্টরি' ডিরেক্টরিটি, যদি প্রোগ্রামটি আপেক্ষিক পথ ব্যবহার করে তবে স্বয়ংক্রিয়ভাবে পূর্ণ হয়?
colemik

3
আপনি যখন #include <windows.h>, উইন্ডোজ স্বয়ংক্রিয়ভাবে char*এক্সিকিউটেবল পাথে একটি রাখে _pgmptr। আপনি যদি কেবল উইন্ডোজে কাজ করে থাকেন তবে আপনাকে অতিরিক্ত ফাংশনগুলি কল করতে বা জাঙ্কটি ধরে রাখার দরকার নেই।
rsethc

1
যদিও মন্তব্যটি তিন বছর আগের থেকে, আমি আরএসএটিসি-র মন্তব্য সম্পর্কে প্রসারিত করতে চাই _pgmptr। এমএসডিএন ডকুমেন্টেশনে বলা হয়েছে যে _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
আমি মনে করি এটি এখানে একমাত্র উত্তর যা প্রশ্নের উত্তর দেয় এবং উইন্ডোজ এবং লিনাক্স উভয়ের ক্ষেত্রেই তা করে। চমৎকার কাজ.
ফ্রাঙ্ক এস্কজারবা 19

6
/ প্রোক / পিড / এক্সের জন্য উত্সাহ - কোনও কারণে ওএস এক্সে সমর্থিত নয়।
ক্রিস লুটজ

24
আমি যখন আমার /procঅংশটি দেখি এমন কোডটি দেখি তখন কিছুটা মারা যায়। সমস্ত বিশ্ব লিনাক্স নয় এবং এমনকি একটি প্ল্যাটফর্মের /procসংস্করণ থেকে সংস্করণে, আর্চ থেকে আর্চ ইত্যাদিতে পরিবর্তন সাপেক্ষে বিবেচিত হওয়া উচিত
আসভেকাউ

4
যদি তারা লিনাক্সে অ্যালাইজড কমান্ড ব্যবহার করে আরগভি [0] "কমান্ডের নাম" বা প্রসারিত হয়?
অ্যান্ডি ডেন্ট

20
char pBuf[256]; size_t len = sizeof(pBuf);সমাধানটি আরও পরিষ্কারভাবে যুক্ত করতে কীভাবে অ্যাড করবেন।
Charles.cc.hsu

166

আপনার প্রোগ্রামটি প্রথম শুরু হওয়ার সাথে সাথে যদি আপনি বর্তমান ডিরেক্টরিটি আনেন, তবে কার্যকরভাবে আপনার প্রোগ্রামটি আপনার প্রোগ্রামটি শুরু হয়েছিল have একটি ভেরিয়েবলের মধ্যে মান সংরক্ষণ করুন এবং এটি আপনার প্রোগ্রামে পরে উল্লেখ করুন। এটি বর্তমান এক্সিকিউটেবল প্রোগ্রাম ফাইলটি ধারণ করে এমন ডিরেক্টরি থেকে পৃথক । অগত্যা এটি একই ডিরেক্টরি নয়; যদি কেউ কমান্ড প্রম্পট থেকে প্রোগ্রামটি চালায়, তবে প্রোগ্রামটি চালানো হচ্ছে তবে প্রোগ্রাম ফাইলটি অন্য কোথাও বাস করা সত্ত্বেও প্রোগ্রামটি কমান্ড প্রম্পটের বর্তমান ওয়ার্কিং ডিরেক্টরি ।

getcwd একটি POSIX ফাংশন এবং সমস্ত POSIX অনুগত প্ল্যাটফর্মগুলি বক্সের বাইরে সমর্থন করে। আপনাকে বিশেষ কিছু করতে হবে না (ইউনিক্সে ডান শিরোনামগুলি unistd.h এবং উইন্ডোতে ডিরেক্ট।

যেহেতু আপনি একটি সি প্রোগ্রাম তৈরি করছেন এটি ডিফল্ট সি রান টাইম লাইব্রেরির সাথে লিঙ্ক করবে যা সিস্টেমে সমস্ত প্রক্রিয়া দ্বারা যুক্ত করা হয়েছে (বিশেষভাবে তৈরি করা ব্যতিক্রমগুলি এড়ানো হয়েছে) এবং এটি ডিফল্টরূপে এই ফাংশনটি অন্তর্ভুক্ত করবে। সিআরটি কখনই বাহ্যিক লাইব্রেরি হিসাবে বিবেচিত হয় না কারণ এটি ওএসকে বুনিয়াদি মান সম্মত ইন্টারফেস সরবরাহ করে।

উইন্ডোতে 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
আপনার যুক্ত হওয়া উচিত এমনকি কিছু ডকুমেন্টেশন যদি বলে যে সিসারেন্টপথটি নালার হতে পারে এবং getcwd দ্বারা বরাদ্দ করা হবে getcwd ম্যাক ওএসে কিছু বরাদ্দ করে নিঃশব্দে আপনার প্রোগ্রামটি ক্র্যাশ করে বলে মনে হচ্ছে না
জানুস

4
একটি ছোট ত্রুটি আছে, তবে দুর্ভাগ্যক্রমে আমি এখনও সম্পাদনা করতে পারি না .. লাইন 10: সিকোর্নপথ: সিকোর্নপথ হওয়া উচিত
লিপিস

8
উইন্ডোজে আইএমও POSIXy- নামক ফাংশন (যার মধ্যে কিছুগুলি আন্ডারস্কোর দিয়ে শুরু হয়) সাধারণত এড়ানো উচিত। এগুলি আসল উইন্ডোজ এপিআই নয় বরং সিআরটি। আপনি যে উইন্ডোজ এপিআই ব্যবহার করতে চান তা হ'ল গেটকন্ট্রেন্টডাইরেক্টরি ()। এমএসডিএন.মাইক্রোসফট.এইন.উস
লাইব্রেরি

6
মাইকের উত্তরটি সঠিক। "বর্তমান ডিরেক্টরি" বাইনারি যে ডিরেক্টরি থেকে চালিত হয় তার মতো হয় না। উদাহরণস্বরূপ, যদি কোনও অ্যাপ্লিকেশন উইন্ডোজে কোনও পরিষেবা হিসাবে চালিত হয় তবে বর্তমান ডিরেক্টরি সম্ভবত সি: \ উইন্ডোজ \ সিস্টেম 32 হবে, বাইনারি ডায়ার আলাদা।
লাকি লুক

42

এটি সিপিপ্লসপ্লাস ফোরামের

উইন্ডোতে:

#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 );
}

এইচপি-ইউএক্স এ:

#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
উইন্ডোজ সমাধানটি অ-এএনএসআই অক্ষরগুলিকে পরিচালনা করবে না। আপনার সম্ভবত সম্ভবত getModuleFileNameW ব্যবহার করা উচিত এবং এটি ইউটিএফ -8 এ স্পষ্টত রূপান্তর করা উচিত (যখনই আপনি যখন একটি ফাইল সিস্টেম কমান্ড জারি করতে হবে তখন এটি আবার রূপান্তর করতে সতর্ক থাকবেন)।
অ্যাড্রিয়ান ম্যাকার্থি

3
উইন্ডোজ সমাধানের জন্য, আমি error: cannot convert 'char*' to 'LPWCH {aka wchar_t*}' for argument '2' to 'DWORD GetModuleFileNameW(HMODULE, LPWCH, DWORD)'MinGW এর সাথে সংকলন করার সময় ত্রুটিটি পাই ।
হ্যালোগডবাই

2
@ অ্যাড্রিয়ান, আমি সাধারণত উইন্ডোজ প্রোগ্রামার নই, তবে আপনার সংকলকটি স্বয়ংক্রিয়ভাবে ফাংশনগুলির _W () স্বাদ ব্যবহার করতে বলার জন্য কোনও সংজ্ঞা বা কোনও উপায় নেই?
অক্টোপাস

1
@ অ্যাক্টোপাস: প্রশস্ত কলগুলি ব্যবহার করতে আপনাকে ডাব্লুসিএইচআর (চরের পরিবর্তে) এবং স্টাডি :: ডাব্লু স্ট্রিং (স্টাড :: স্ট্রিংয়ের পরিবর্তে) ব্যবহার করতে হবে।
অ্যাড্রিয়ান ম্যাকার্থি

29

আপনি যদি লাইব্রেরি ব্যতীত কোনও মানক উপায় চান: না। কোনও ডিরেক্টরিের পুরো ধারণাটি স্ট্যান্ডার্ডের মধ্যে অন্তর্ভুক্ত নয়।

যদি আপনি সম্মত হন যে কাছাকাছি-মানসম্পন্ন লাইবের উপর কিছু (পোর্টেবল) নির্ভরতা ঠিক আছে: ব্যবহার করুন লাইবের বুস্টের ফাইল সিস্টেম লাইব্রেরিটি ব্যবহার করুন এবং প্রাথমিক_পথের জন্য জিজ্ঞাসা করুন ()

আইএমএইচও যা আপনার কাছে যতটা কাছাকাছি পাওয়া যায়, ভাল কর্মের সাথে (বুস্টটি একটি প্রতিষ্ঠিত উচ্চমানের গ্রন্থাগারের সেট)


8
বুস্ট ডক্স থেকে: টেমপ্লেট <বর্গের পথ> কনস্ট পাথ এবং প্রাথমিক_পথ (); রিটার্ন: প্রধান () এ প্রবেশের সময় কারেন্ট_পথ ()। এবং কারেন্ট_পথ () হ'ল 'পসিক্স getcwd () দ্বারা'। এটি প্রশ্নকর্তা অনুরোধ করেননি।
জোনাথন লেফলার

দেখতে boost.org/doc/libs/1_46_1/libs/filesystem/v3/doc/... জন্য বুস্ট 1.46.1
moala

যেমন মন্তব্য করা হয়েছে, এটি বাইনারিটি যেখান থেকে ডাকা হয়েছিল, সেখান থেকে এমন পথ দেয় যা বাইনারিটির পথে নয় ... কারণ এটি অন্য ফোল্ডার থেকে শুরু করা যেতে পারে।
jpo38

21

ফাইল সিস্টেম টিএস এখন একটি স্ট্যান্ডার্ড (এবং জিসিসি 5.3+ এবং ক্ল্যাং 3.9+ দ্বারা সমর্থিত), যাতে আপনি current_path()এটি থেকে ফাংশনটি ব্যবহার করতে পারেন :

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

ফাইলসিসটেমটি অন্তর্ভুক্ত করতে জিসিসি (5.3+) এ আপনাকে ব্যবহার করতে হবে:

#include <experimental/filesystem>

এবং আপনার কোডের সাথে লিঙ্ক করুন -lstdc++fs পতাকা ।

আপনি যদি মাইক্রোসফ্ট ভিজ্যুয়াল স্টুডিও সহ ফাইল সিস্টেমটি ব্যবহার করতে চান তবে এটি পড়ুন


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

আমি জানি যে এই মুহূর্তে একটি উত্তর দিতে খুব দেরি হয়ে গেছে তবে আমি দেখতে পেয়েছি যে উত্তরগুলির কোনওটিই আমার নিজের সমাধান হিসাবে আমার পক্ষে কার্যকর ছিল না। আপনার সিডাব্লুডি থেকে আপনার বিন ফোল্ডারে যাওয়ার খুব সহজ উপায় হ'ল:

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("\\"));

আমি মনে করি এটি কাজ করা উচিত তবে এটি পরীক্ষা করা হয়নি, সুতরাং মন্তব্যটি যদি এটি কাজ করে তবে প্রশংসা হবে বা যদি না হয় তবে একটি সমাধান করুন।


হ্যাঁ, এটি উইন্ডোতেও কাজ করে। আমি মনে করি এটিই সেরা সমাধান। আমি যতদূর জানি অর্গভি [0] সর্বদা কার্যকর সম্পাদকের পথে রাখে।
ওডজু

4
argv[0]খুব সুন্দর ধারণা, তবে দুর্ভাগ্যজনকভাবে আমি লিনাক্সে যা পাচ্ছি তা হ'ল "./my_executable_name" বা "./make/my_executable_name"। মূলত আমি যা পাই তা সম্পূর্ণভাবে নির্ভর করে যে আমি এটি কীভাবে চালু করব
Xeverous

@ ব্যভিচারী: তাহলে কি? যদি আমার এক্সিকিউটেবলের সাথে সম্পর্কিত কিছু ফাইল থাকে তবে এটি খোলার প্রয়োজন, আপনার ক্ষেত্রে "./" বা "./makes/" থেকে কাজ করা উচিত। "।" বর্তমান কার্যনির্বাহী ডিরেক্টরি, এবং আরজিভি [0] আপনাকে সেখান থেকে সম্পাদনযোগ্য সম্পর্কিত আপেক্ষিক পথটি বলতে দেবে, এটি ওপিটি ঠিক কী চায়। এটি যে কোনও ক্ষেত্রে আমার যা প্রয়োজন ঠিক তা-ই।
নিলো

9

না, কোনও স্ট্যান্ডার্ড উপায় নেই। আমি বিশ্বাস করি যে সি / সি ++ মানক এমনকি ডিরেক্টরিগুলির অস্তিত্বও (বা অন্যান্য ফাইল সিস্টেম সংস্থাগুলি) বিবেচনা করে না।

Windows এ GetModuleFileName () যখন বর্তমান প্রক্রিয়ার এক্সিকিউটেবল ফাইলের সম্পূর্ণ পাথ ফিরে আসবে hModule প্যারামিটার সেট করা হয় শূন্য । আমি লিনাক্স সাহায্য করতে পারি না।

এছাড়াও আপনি বর্তমান ডিরেক্টরিটি বা প্রোগ্রামের চিত্র / এক্সিকিউটেবলের যে ডিরেক্টরিটি থাকে সেই ডিরেক্টরিটি চান কিনা তাও আপনাকে স্পষ্ট করে বলতে হবে। যেহেতু এটি দাঁড়িয়েছে আপনার প্রশ্নটি এই বিষয়টিতে কিছুটা অস্পষ্ট।


9

উইন্ডোজে সহজ উপায় হ'ল _get_pgmptrফাংশনটি stdlib.hকোনও স্ট্রিংয়ের পয়েন্টার পেতে ব্যবহার করা যা এক্সিকিউটেবলের নাম সহ এক্সিকিউটেবলের পরম পাথকে উপস্থাপন করে।

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

8

আরজিভি [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;
}

রান করার সময় এটি আউটপুট হয়:

জেরেমি @ জেরেমি-ডেস্কটপ: ~ / ডেস্কটপ $। / সেরা / হোম / জেরেমি / ডেস্কটপ /. /
টেষ্ট


আরজিভি [0]-তে কোনও নিরঙ্কুশ পথ দেওয়া হয়েছে কিনা তা দেখতে আপনার একটি চেক দরকার। তবে আরও গুরুত্বপূর্ণ বিষয়, যদি চিত্রটি প্যাথের মাধ্যমে অবস্থিত হয়? লিনাক্স পুরো পথ পূরণ করে বা কমান্ড লাইনের ঠিক কী?
মাইকেল বুড়

মাইক বি যেমন উল্লেখ করেছেন, এটি একটি সাধারণ-সমাধান; এটি কিছু খুব সীমিত পরিস্থিতিতে কাজ করে। মূলত, কেবলমাত্র যখন আপনি কোনও আপেক্ষিক পথের নাম দ্বারা কমান্ডটি চালান - এবং আপনি যখন চালনা করেন তখন এটি সমস্ত মার্জিত হয় না test......... এর পরিবর্তে / বিন / প্রোগ্রাম
জোনাথন লেফলার

আপনি যদি বর্তমান ডিরেক্টরিটির তুলনায় আরগভ [0] এর সম্ভাব্য আপেক্ষিক পথটি সমাধান করেন (কারণ আরজিভি [0] হতে পারে "../../myprogram.exe"), তবে প্রশ্নের উত্তর দেওয়ার সম্ভবত এটি সবচেয়ে নিরাপদ উপায়। এটি সর্বদা কাজ করবে এবং বহনযোগ্য (এটি এমনকি অ্যান্ড্রয়েডেও কাজ করে!)।
jpo38

7

উইন 32 এর জন্য গেটকারেন্টের ডিরেক্টরীতে কৌশলটি করা উচিত।


নেই এই ফাংশন সাথে বড় ধরা : মাল্টি অ্যাপ্লিকেশন এবং ভাগ গ্রন্থাগার কোড GetCurrentDirectory ফাংশন ব্যবহার করা উচিত নয় এবং আপেক্ষিক pathnames ব্যবহার এড়িয়ে চলা উচিত । আপনি যদি এই অনুমানের সাথে কাজ করতে পারেন তবে এটি সেরা সমাধান।
ম্যাকলিয়ারি

6

আপনি সেই উদ্দেশ্যে আরগভি [0] ব্যবহার করতে পারবেন না, সাধারণত এটি সম্পাদনযোগ্যের পুরো পথ ধারণ করে তবে সংক্ষেপে নয় - ক্ষেত্রে স্বেচ্ছাচারিত মান দিয়ে প্রক্রিয়া তৈরি করা যেতে পারে।

এছাড়াও আপনার মনে রাখবেন, এক্সিকিউটেবলের সাথে বর্তমান ডিরেক্টরি এবং ডিরেক্টরি দুটি ভিন্ন জিনিস, সুতরাং getcwd () আপনাকেও সহায়তা করবে না।

উইন্ডোজে লিনাক্স রিড / ডেভ / প্রোক / প্রোআইডি / .. ফাইলগুলিতে গেটমোডুলফিলনাম () ব্যবহার করুন ।


3

এখানে কেবল নির্লজ্জভাবে গাদা করার জন্য ...

কোনও স্ট্যান্ডার্ড সমাধান নেই, কারণ ভাষাগুলি অন্তর্নিহিত ফাইল সিস্টেমগুলির অজ্ঞেয়বাদী, তাই অন্যরা যেমন বলেছে, ডিরেক্টরি ভিত্তিক ফাইল সিস্টেমের ধারণাটি সি / সি ++ ভাষার বাইরে নয়।

সর্বোপরি, আপনি বর্তমান চলমান ডিরেক্টরিটি চান না, তবে প্রোগ্রামটি যে ডিরেক্টরিটি চালাচ্ছে তা অবশ্যই প্রোগ্রামটিকে কোথায় পেয়েছে তা বিবেচনায় নিতে হবে - যেমন এটি একটি কাঁটাচামচ ইত্যাদির মাধ্যমে নতুন প্রক্রিয়া হিসাবে তৈরি হয়েছিল etc. একটি প্রোগ্রাম যে ডিরেক্টরিতে চালিত হয়েছে সেগুলি পাওয়ার জন্য, যেমন সমাধানগুলি প্রমাণ করেছে যে, আপনাকে অপারেটিং সিস্টেমের প্রক্রিয়া নিয়ন্ত্রণ কাঠামো থেকে সেই তথ্যটি পাওয়া উচিত, যা এই প্রশ্নের একমাত্র কর্তৃত্ব। সুতরাং, সংজ্ঞা অনুসারে, এটি একটি ওএস নির্দিষ্ট সমাধান।


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

পসিক্স প্ল্যাটফর্মে, আপনি getcwd () ব্যবহার করতে পারেন

Windows এ, আপনি ব্যবহার করতে পারেন _getcwd () , এর ব্যবহার getcwd () এর করা হয়েছে।

স্ট্যান্ডার্ড লাইব্রেরিগুলির জন্য, যদি বুস্ট আপনার পক্ষে পর্যাপ্ত মানসম্পন্ন হয় তবে আমি বুস্ট :: ফাইল সিস্টেমের পরামর্শ দিয়েছিলাম তবে তারা প্রস্তাব থেকে পথের স্বাভাবিকীকরণ সরিয়ে নিয়েছে বলে মনে হয়। সম্পূর্ণ স্ট্যান্ডার্ড সমাধানের জন্য টিআর 2 সহজেই উপলব্ধ না হওয়া পর্যন্ত আপনাকে অপেক্ষা করতে হতে পারে ।


10
getcwd () প্রশ্নকারী যা বলেছিল তা করে না।
জোনাথন লেফলার

এটি কি নয় যে গৃহীত উত্তরগুলি getcwd () ব্যবহার করে, বা আমি কেবল বুঝতে পারি না?
Sнаđошƒаӽ

আমি উত্সাহিত করেছি কারণ আপনিই সেই ব্যক্তি যিনি এসেছিলেন যা প্রথমে সঠিক উত্তর হিসাবে বিবেচিত হয়।
অর্ণাড

এই উত্তরটি এমনকি প্রশ্নের সমাধান করার চেষ্টা করে না। এটা লিখতে লজ্জা।
হ্যালো ওয়ার্ল্ড

1

আপেক্ষিক পাথের জন্য, আমি যা করেছি তা এখানে। আমি এই প্রশ্নের বয়স সম্পর্কে সচেতন, আমি কেবল একটি সহজ উত্তর অবদান রাখতে চাই যা বেশিরভাগ ক্ষেত্রে কাজ করে:

বলুন আপনার মতো পথ রয়েছে:

"path/to/file/folder"

কোনও কারণে, গ্রহনে তৈরি লিনাক্স-বিল্ট এক্সিকিউটেবলগুলি এটির সাথে কাজ করে। যাইহোক, উইন্ডোজ খুব বিভ্রান্ত হয়ে যদি এইরকম কোনও পথ দিয়ে কাজ করে!

উপরে বর্ণিত হিসাবে এক্সিকিউটেবলের বর্তমান পাথটি পাওয়ার বেশ কয়েকটি উপায় রয়েছে তবে বেশিরভাগ ক্ষেত্রে আমি সবচেয়ে সহজ উপায় খুঁজে পাই যে এটি আপনার পথের এফআরন্টে যুক্ত করে:

"./path/to/file/folder"

কেবল "./" যুক্ত করা আপনার বাছাই করা উচিত! :) তারপরে আপনি যে ডিরেক্টরিটি চান তা থেকে লোড করা শুরু করতে পারেন, যতক্ষণ না এটি এক্সিকিউটেবলের সাথে থাকে।

সম্পাদনা: আপনি যদি কোড :: ব্লকগুলি থেকে এক্সিকিউটেবলকে চালু করার চেষ্টা করেন তবে এটি কাজ করবে না যদি কোনও কারণ হিসাবে, কোড :: ব্লকগুলি জিনিসগুলি ঠিকমতো লোড করে না ...: D

সম্পাদনা 2: আমি কিছু নতুন জিনিস পেয়েছি তা হ'ল আপনি যদি নিজের কোডে এই জাতীয় স্থিতির পথটি নির্দিষ্ট করেন (উদাহরণস্বরূপ d ডাটা এমন কিছু যা আপনার বোঝাতে হবে):

"resources/Example.data"

তারপরে যদি আপনি প্রকৃত ডিরেক্টরি থেকে আপনার অ্যাপ্লিকেশনটি চালু করেন (বা উইন্ডোজে আপনি একটি শর্টকাট তৈরি করেন এবং আপনার অ্যাপ্লিকেশন ডায়ারে ওয়ার্কিং ডির সেট করেন) তবে এটি এর মতো কাজ করবে। নিখোঁজ রিসোর্স / ফাইল পাথ সম্পর্কিত সমস্যাগুলি ডিবাগ করার সময় এটি মনে রাখবেন। (বিশেষত আইডিই থেকে আইডিই থেকে বিল্ড এক্সপি চালু করার সময় ভুল কাজ করার ধীর সেট করে)


1

একটি লাইব্রেরির সমাধান (যদিও আমি জানি এটির জন্য জিজ্ঞাসা করা হয়নি)। আপনি কিউটি ব্যবহার করতে গেলে: QCoreApplication::applicationDirPath()


1

কেবল আমার দুটি সেন্ট, তবে নিম্নলিখিত কোডগুলি C ++ 17 তে পোর্টেবলভাবে কাজ করে না?

#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]);

আরজিভি [0] ধারণার জন্য @ সাম রেডওয়ে ধন্যবাদ। এবং অবশ্যই, আমি বুঝতে পারি যে সি ++ 17 বহু বছর ধরে ছিল না যখন ওপি প্রশ্ন করেছিল।


0

ফাইলস্টেমের বুস্টটি initial_path()পসিক্সের মতো আচরণ করে getcwd()এবং আপনি যা চান তা নিজে করে না, তবে সংযোজন করেargv[0] তাদের করা উচিত।

আপনি খেয়াল করতে পারেন যে ফলাফলটি সর্বদা সুন্দর হয় না - আপনি /foo/bar/../../baz/a.outবা জাতীয় জিনিস পেতে পারেন/foo/bar//baz/a.out , তবে আমি বিশ্বাস করি যে এটি সর্বদা কার্যকর বৈধ পথের ফলশ্রুতি দেয় যা এক্সিকিউটেবলের নাম দেয় (নোট করুন যে কোনও পথে ক্রমাগত স্ল্যাশগুলি ভেঙে গেছে)।

আমি এর আগে একটি সমাধান ব্যবহার করে লিখেছিলাম envp(তৃতীয় যুক্তি main()যা লিনাক্সে কাজ করেছিল তবে উইন্ডোজটিতে কার্যক্ষম বলে মনে হচ্ছে না, তাই আমি অন্য যেভাবে আগে করেছি ঠিক তেমন সমাধানের পরামর্শ দিচ্ছি, তবে কেন এটি আসলে সঠিক তা নিয়ে অতিরিক্ত ব্যাখ্যা দিয়ে) ফলাফল সুন্দর না হলেও।


0

মিনোক যেমন উল্লেখ করেছেন, তেমন কোনও কার্যকারিতা নির্দিষ্ট করে ইন সি সি স্ট্যান্ডার্ড বা সি ++ স্ট্যান্ডার্ড নেই। এটি খাঁটি ওএস-নির্দিষ্ট বৈশিষ্ট্য হিসাবে বিবেচনা করা হয় এবং এটি পসিক্স স্ট্যান্ডার্ডে নির্দিষ্ট করা হয়, উদাহরণস্বরূপ।

Thorsten79 ভাল পরামর্শ দিয়েছেন, এটা Boost.Filesystem লাইব্রেরী। তবে, আপনি যদি আপনার প্রোগ্রামের জন্য বাইনারি আকারে কোনও লিঙ্ক-টাইম নির্ভরতা না চান তবে এটি অসুবিধে হতে পারে।

আমি প্রস্তাবিত একটি ভাল বিকল্প হ'ল 100% শিরোনাম-কেবলমাত্র এসটিএলসফট সি ++ গ্রন্থাগারগুলি ম্যাথিউ উইলসন (সি ++ সম্পর্কে অবশ্যই পাঠ্য বইয়ের লেখক) এর সংগ্রহ। পোর্টেবল ফেইসড রয়েছে প্ল্যাটফর্মএসটিএল সিস্টেম-নির্দিষ্ট এপিআইতে অ্যাক্সেস দেয়: উইন্ডোজ উইনস্টল এবং ইউনিক্সে ইউনিক্সএসটিএল, সুতরাং এটি বহনযোগ্য সমাধান। সমস্ত সিস্টেম-নির্দিষ্ট উপাদানগুলি বৈশিষ্ট্য এবং নীতিগুলির ব্যবহারের সাথে নির্দিষ্ট করা হয়, সুতরাং এটি এক্সটেনসিবল কাঠামো। অবশ্যই ফাইল সিস্টেম লাইব্রেরি দেওয়া আছে।


0

লিনাক্স বাশ কমান্ড যা পূর্বে নাম দেয় প্রোগ্রামটির পথে যাওয়ার প্রতিবেদন করবে।

এমনকি যদি কেউ আপনার প্রোগ্রামের মধ্যে থেকে কমান্ডটি জারি করতে পারে এবং আউটপুটটি কোনও টিএমপি ফাইলের দিকে নির্দেশ করতে পারে এবং প্রোগ্রামটি পরবর্তী সময়ে সেই টিএমপি ফাইলটি পড়তে পারে তবে তা আপনাকে জানাতে পারে না যে সেই প্রোগ্রামটি কার্যকর হয় কিনা। এটি কেবল আপনাকে জানায় যে সেই নামের একটি প্রোগ্রাম কোথায় রয়েছে।

যা প্রয়োজন তা হ'ল আপনার প্রক্রিয়া আইডি নম্বরটি পাওয়া এবং নামের পথটি বিশ্লেষণ করা

আমার প্রোগ্রামে আমি জানতে চাই যে প্রোগ্রামটি ব্যবহারকারীর বিন ডিরেক্টরি থেকে বা পথে বা অন্য / ইউএসআর / বিন থেকে চালানো হয়েছে কিনা। / usr / বিনটিতে সমর্থিত সংস্করণ থাকবে। আমার অনুভূতি হ'ল লিনাক্সে একমাত্র সমাধান যা পোর্টেবল is



0

সি ++ 11 থেকে পরীক্ষামূলক ফাইল সিস্টেম এবং সি ++ 14-সি ++ 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বিশ্বব্যাপী নামস্থান করতে।
ক্যাসিও রেনান

আমি অনুমান করি সি ++ ১৪ টি পরীক্ষামূলক :: ফাইল সিস্টেমের পরে আর ব্যবহার করা হয়নি, তাই আপনি কি এই সম্পর্কে ভুলে যেতে পারেন? (প্রথম # আই শাখায় যায়)
টারমোপিকারো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.