সি ++ তে _টাইমেন () এবং প্রধান () এর মধ্যে পার্থক্য কী?


224

আমি যদি নিম্নলিখিত মূল () পদ্ধতিটি দিয়ে আমার সি ++ অ্যাপ্লিকেশনটি চালিত করি তবে সবকিছু ঠিক আছে:

int main(int argc, char *argv[]) 
{
   cout << "There are " << argc << " arguments:" << endl;

   // Loop through each argument and print its number and value
   for (int i=0; i<argc; i++)
      cout << i << " " << argv[i] << endl;

   return 0;
}

আমি যা প্রত্যাশা করি তা পেয়েছি এবং আমার যুক্তিগুলি মুদ্রিত হয়েছে।

যাইহোক, আমি যদি _tmain ব্যবহার করি:

int _tmain(int argc, char *argv[]) 
{
   cout << "There are " << argc << " arguments:" << endl;

   // Loop through each argument and print its number and value
   for (int i=0; i<argc; i++)
      cout << i << " " << argv[i] << endl;

   return 0;
}

এটি প্রতিটি আর্গুমেন্টের প্রথম চরিত্রটি প্রদর্শন করে।

এর ফলে কি পার্থক্য রয়েছে?

উত্তর:


357

_tmainসি ++ তে বিদ্যমান নেই। mainআছে।

_tmain একটি মাইক্রোসফ্ট এক্সটেনশন।

main, সি ++ স্ট্যান্ডার্ড অনুযায়ী, প্রোগ্রামটির প্রবেশের পয়েন্ট। এটিতে এই দুটি স্বাক্ষরের একটি রয়েছে:

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

মাইক্রোসফ্ট একটি ওয়াইন যোগ করেছে যা এটির সাথে দ্বিতীয় স্বাক্ষরটি প্রতিস্থাপন করে:

int wmain(int argc, wchar_t* argv[]);

এবং তারপরে, ইউনিকোড (ইউটিএফ -16) এবং তাদের মাল্টিবাইট অক্ষর সেটগুলির মধ্যে স্যুইচ করা সহজ করার জন্য, তারা সংজ্ঞায়িত করেছে _tmainযে, যদি ইউনিকোড সক্ষম করা থাকে তবে হিসাবে সংকলিত হয় wmainএবং অন্যথায় main

আপনার প্রশ্নের দ্বিতীয় অংশ হিসাবে, ধাঁধার প্রথম অংশটি হ'ল আপনার মূল ফাংশনটি ভুল। wmainএকটি wchar_tযুক্তি নেওয়া উচিত , না char। যেহেতু সংকলক mainফাংশনটির জন্য এটি প্রয়োগ করে না , আপনি একটি প্রোগ্রাম পান যেখানে wchar_tস্ট্রিংগুলির একটি অ্যারে mainফাংশনে প্রেরণ করা হয় , যা তাদের charস্ট্রিং হিসাবে ব্যাখ্যা করে ।

এখন, ইউটিএফ -16 এ, ইউনিকোড সক্ষম করার সময় উইন্ডোজ দ্বারা ব্যবহৃত অক্ষর সেট করা হয়েছে, সমস্ত ASCII অক্ষর \0ASCII মান অনুসারে বাইটের জুটি হিসাবে উপস্থাপিত হয়।

এবং যেহেতু x86 সিপিইউ ছোট-এন্ডিয়ান, এই বাইটগুলির ক্রমটি অদলবদল করা হয়, যাতে ASCII মানটি প্রথমে আসে, তারপরে নাল বাইট হয়।

এবং একটি চর স্ট্রিং মধ্যে, স্ট্রিং সাধারণত কিভাবে সমাপ্ত হয়? হ্যাঁ, নাল বাইট দ্বারা সুতরাং আপনার প্রোগ্রামটি স্ট্রিংগুলির একটি গোছা প্রত্যেকে প্রত্যেকে দীর্ঘ বাইট দেখে sees

সাধারণভাবে উইন্ডোজ প্রোগ্রামিং করার সময় আপনার কাছে তিনটি বিকল্প রয়েছে:

  • সুস্পষ্টভাবে ইউনিকোড ব্যবহার করুন (কল উইমেন, এবং প্রতিটি উইন্ডোজ এপিআই ফাংশনের জন্য যা চর-সম্পর্কিত আর্গুমেন্ট গ্রহণ করে, -Wফাংশনের সংস্করণটি কল করুন Create উইন্ডো উইন্ডোর পরিবর্তে, ক্রিয়েটওয়াইন্ডো ডাব)। এবং charব্যবহার না করে wchar_t, এবং আরও
  • স্পষ্টতই ইউনিকোড অক্ষম করুন। মুখ্য কল করুন এবং ক্রিয়েট উইন্ডোএ, এবং charস্ট্রিংয়ের জন্য ব্যবহার করুন ।
  • উভয়কে অনুমতি দিন। (_tmain এবং ক্রিয়েট উইন্ডোকে কল করুন, যা প্রধান / _tmain এবং ক্রিয়েটওয়াইন্ডো / ক্রিয়েটওয়াইনডাব্লুতে সংশোধন করে) এবং গৃহস্থালি / wchar_t এর পরিবর্তে TCHAR ব্যবহার করে।

উইন্ডোজের দ্বারা সংজ্ঞায়িত স্ট্রিং ধরণের ক্ষেত্রেও এটি একই প্রযোজ্য .h

নোট করুন যে এই সমস্তগুলি মাইক্রোসফ্ট নির্দিষ্ট। টিসিএইচএআর কোনও স্ট্যান্ডার্ড সি ++ টাইপ নয়, এটি উইন্ডোজ এইচডি-তে সংজ্ঞায়িত ম্যাক্রো। wmain এবং _tmain এছাড়াও শুধুমাত্র মাইক্রোসফ্ট দ্বারা সংজ্ঞায়িত করা হয়।


6
আমি ভাবছি তারা খুব একটা টিসিআউট সরবরাহ করে কিনা? যাতে কেউ স্রেফ tcout করতে পারে << argv [n]; এবং এটি আনসিতে সিউট এবং ইউনিকোড মোডে ডাব্লুসিআউট সমাধান করে? আমি সন্দেহ করি যে এই পরিস্থিতিতে তার জন্য দরকারী হতে পারে। এবং +1 অবশ্যই, দুর্দান্ত উত্তর :)
জোহানেস স্কাউব -

1
ইউনিকোডে অক্ষম করার কী অসুবিধা হবে?
joshcomley

2
-1 তালিকাভুক্ত তিনটি বিকল্পের কোনওটিই ব্যবহারিক নয়। উইন্ডোজ প্রোগ্রামের ব্যবহারিক উপায় হ'ল সংজ্ঞা দেওয়া UNICODE। আর সি ++ ইত্যাদি জন্য কিছু অন্যান্য সমন্বয় সহ সামনে <windows.h>। তারপরে ইউনিকোড ফাংশনগুলি ব্যবহার করুন CreateWindow(সাধারণভাবে Wশেষে প্রয়োজন নেই )।
চিয়ার্স এবং এইচটিএইচ - আলফ

11
কেন আপনি একে আরও ব্যবহারিক বলে মনে করেন?
jalf

1
"..._ টেমেনটি কেবল মাইক্রোসফ্ট দ্বারাও সংজ্ঞায়িত করা হয়" আপনার শেষ অনুচ্ছেদটি একেবারেই ভুল , _ডেমিনটি আরএডি স্টুডিওর সি ++ বিল্ডারে ঠিক একইভাবে প্রয়োগ করা হয়েছে। আসলে, সি ++ বিল্ডারের ডিফল্ট _TCHAR ম্যাপিংয়ের অধীনে কেবল প্রধান ব্যবহার ব্যর্থ হবে।
b1nary.atr0phy

35

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

সঠিক ঘোষণাটি হ'ল

 int _tmain(int argc, _TCHAR *argv[]) 

যদি ম্যাক্রো ইউনিকোডিকে সংজ্ঞায়িত করা হয় তবে তা প্রসারিত হয়

int wmain(int argc, wchar_t *argv[])

অন্যথায় এটি প্রসারিত হয়

int main(int argc, char *argv[])

আপনার সংজ্ঞা প্রতিটি এক বিট জন্য যায়, এবং (আপনি যদি ইউনিকোড সংজ্ঞায়িত করা হয়) প্রসারিত হবে

 int wmain(int argc, char *argv[])

যা কেবল সাধারণ ভুল is

std :: cout ASCII অক্ষরের সাথে কাজ করে। আপনি যদি বিস্তৃত অক্ষর ব্যবহার করেন তবে আপনার স্টাডি :: ডাব্লুসিএইচআউট দরকার।

এই মত কিছু চেষ্টা করুন

#include <iostream>
#include <tchar.h>

#if defined(UNICODE)
    #define _tcout std::wcout
#else
    #define _tcout std::cout
#endif

int _tmain(int argc, _TCHAR *argv[]) 
{
   _tcout << _T("There are ") << argc << _T(" arguments:") << std::endl;

   // Loop through each argument and print its number and value
   for (int i=0; i<argc; i++)
      _tcout << i << _T(" ") << argv[i] << std::endl;

   return 0;
}

অথবা আপনি প্রশস্ত বা সংকীর্ণ অক্ষর ব্যবহার করবেন কিনা তা আগে থেকেই সিদ্ধান্ত নিতে পারেন। :-)

আপডেট হয়েছে 12 নভেম্বর 2013:

Traditionalতিহ্যবাহী "TCHAR" কে "_TCHAR" এ পরিবর্তন করেছেন যা দেখে মনে হয় এটি সর্বশেষতম ফ্যাশন। দুটোই ঠিকঠাক কাজ করে।

শেষ আপডেট


1
"এটি একটি মাইক্রোসফ্ট এক্সটেনশন এবং অন্য কোনও সংকলক নিয়ে কাজ করবে না।" আরএডি স্টুডিও যতটা উদ্বিগ্ন নয়।
b1nary.atr0phy

@ b1naryatr0phy - কেশ বিভক্ত করতে, আপনি যে টুলটি সংযুক্ত করেছেন সেটি "TCHAR" এর পরিবর্তে "_TCHAR" ব্যবহার করে তাই এটি সামঞ্জস্যপূর্ণ নয় (যদিও এটি আমার বক্তব্যটিকে মিথ্যা বলে)। তবে আমার বলা উচিত ছিল "এটি একটি মাইক্রোসফ্ট এক্সটেনশন এবং এটি অন্য কোনও সংকলকগুলিতে কাজ করার গ্যারান্টিযুক্ত নয়"। আমি মূল সংশোধন করব।
মাইকেল জে

@ মিশেলজে আমি মূলত "কোড পরিবর্তনগুলি ..." বিভাগের কথা উল্লেখ করছিলাম, যা ব্যাখ্যা করে যে কেন র‌্যাড স্টুডিও এখন প্রধানের জায়গায় _টমেন ব্যবহার করে এবং বাস্তবে এটি এখন এম্বারকাডেরোর সি ++ বিল্ডারের জন্য স্ট্যান্ডার্ড ডিফল্ট।
b1nary.atr0phy

1
সম্প্রতি দ্বিতীয়বারের মতো এই চার বছরের পুরানো উত্তরটি হ্রাস করা হয়েছে। ডাউনভোটাররা কোন সমস্যাগুলি তারা বুঝতে পারে এবং (যদি সম্ভব হয়) কীভাবে উত্তরকে উন্নত করতে পারে সে সম্পর্কে মন্তব্য করে কোনও মন্তব্য করা ভাল হবে। b1naryatr0phy একটি খারাপভাবে লিখিত বাক্যটি খুঁজে পেয়েছিল, তবে আমি এটি মার্চ মাসে ঠিক করেছি। কোন প্রমাণ প্রশংসিত হবে।
মাইকেল জে

2
এর জন্য জীবন খুব ছোট।
মাইকেল জে

10

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

 cout << _T( "There are " ) << argc << _T( " arguments:" ) << endl;

আসলে, এমএস এই পদ্ধতির প্রস্তাব দেয়, আফাইক। আপনার অ্যাপ্লিকেশনটিকে ইউনিকোড-সচেতন করে তোলা, তারা এটিকে কল করে ... সমস্ত স্ট্রিং ম্যানিপুলেশন ফাংশনের _t সংস্করণটিও ব্যবহার করে।
ডিপ-বি

1
@ ডিপ-বি এবং Windows এ, এই হল কিভাবে আপনি আপনার আবেদন ইউনিকোড-প্রস্তুত (আমি ইউনিকোড-প্রস্তুত -aware করতে মেয়াদের পছন্দ করেন) করতে, যদি এটা উপর ভিত্তি করে ছিল charগুলি আগে। আপনার আবেদন সরাসরি ব্যবহার করে wchar_tতারপর আপনার আবেদন হয় ইউনিকোড।
প্যারাসেবল

5
যাইহোক, আপনি যদি ইউনিকোডে সংকলন করার চেষ্টা করেন, তবে আপনার কোডটি আপনার আউটপুট wchar_t হিসাবে একটি চর-ভিত্তিক কাউটের অভ্যন্তরে সংকলন করবে না, যেখানে এটি wcout হওয়া উচিত ছিল। "টিসিআউট" সংজ্ঞায়নের উদাহরণ হিসাবে মাইকেল জেয়ের উত্তর দেখুন ...
প্যারেসবাল

1
মাইক্রোসফ্ট দ্বারা এটি সুপারিশ করা হয় না তবে কিছুই নয়, কারণ এটি সম্পূর্ণ ভুল। ইউনিকোডের জন্য সংকলন করার সময়, কোডটি স্ট্যান্ডার্ড আউটপুট প্রবাহে পয়েন্টার মান লিখে। -1।
IInspectable

5

ঠিক আছে, মনে হচ্ছে যে প্রশ্নের উত্তর মোটামুটি ভালভাবে দেওয়া হয়েছে, ইউনিকোডের ওভারলোডকে তার দ্বিতীয় প্যারামিটার হিসাবে প্রশস্ত অক্ষরের অ্যারে নেওয়া উচিত। সুতরাং যদি কমান্ড লাইন প্যারামিটারটি "Hello"সম্ভবত শেষ হয় "H\0e\0l\0l\0o\0\0\0"এবং আপনার প্রোগ্রামটি কেবল এটি মুদ্রণ করবে 'H'তবে এটি কী নাল টার্মিনেটর বলে মনে করে।

সুতরাং এখন আপনি ভাবতে পারেন কেন এটি এমনকি সংকলন এবং লিঙ্কগুলি।

ভাল এটি সংকলন করে কারণ আপনাকে কোনও ফাংশনে একটি ওভারলোড সংজ্ঞায়িত করার অনুমতি দেওয়া হয়েছে।

লিঙ্কিং কিছুটা জটিল সমস্যা। সি-তে কোনও সজ্জিত প্রতীক তথ্য নেই সুতরাং এটি কেবল প্রধান নামে একটি ফাংশন খুঁজে পায় finds আরজিসি এবং আরজিভি সম্ভবত সর্বদা কল-স্ট্যাক প্যারামিটার হিসাবে থাকে এমনকি যদি আপনার ফাংশনটি সেই স্বাক্ষর দিয়ে সংজ্ঞায়িত করা হয়, এমনকি যদি আপনার ফাংশনটি এড়িয়ে চলেছে।

যদিও সি ++ তে সজ্জিত চিহ্ন রয়েছে, তবুও এটি অবশ্যই চালাক লিংকের পরিবর্তে মূলটির জন্য সি-লিংকেজ ব্যবহার করে যা প্রতিটি পরিবর্তনের জন্য সন্ধান করে। সুতরাং এটি আপনার উইমেনটি খুঁজে পেয়েছে এবং এটি int wmain(int, wchar_t*[])সংস্করণ হওয়ার ক্ষেত্রে প্যারামিটারগুলি কল-স্ট্যাকের উপরে রাখে ।


ঠিক আছে, তাই আমার কোডগুলি এখন কয়েক বছর ধরে উইন্ডোজ উইডেচারে পোর্ট করতে সমস্যা হয়েছে এবং এটি কেন হয় তা আমি প্রথমবার বুঝতে পেরেছিলাম। এখানে, আমার সমস্ত খ্যাতি নিন! হা হা
লিওনেল

-1

এটিকে টেম্প্লেটিজ করার জন্য একটু চেষ্টা করে, এটি কোনও বস্তুর তালিকার সাথে কাজ করতে পারে।

#include <iostream>
#include <string>
#include <vector>

char non_repeating_char(std::string str){
    while(str.size() >= 2){
        std::vector<size_t> rmlist; 
        for(size_t  i = 1;  i < str.size(); i++){        
            if(str[0] == str[i]) {
                rmlist.push_back(i);
            }      
        }          

        if(rmlist.size()){            
            size_t s = 0;  // Need for terator position adjustment   
            str.erase(str.begin() + 0);
            ++s;
            for (size_t j : rmlist){   
                str.erase(str.begin() + (j-s));                
                ++s;
            }
         continue;
        }
        return str[0];
   }
    if(str.size() == 1) return str[0];
    else return -1;
}

int main(int argc, char ** args)
{
    std::string test = "FabaccdbefafFG";
    test = args[1];
    char non_repeating = non_repeating_char(test);
    Std::cout << non_repeating << '\n';
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.