সি ++ / সিএলআই সিস্টেম :: স্ট্রিং from থেকে স্টেড :: স্ট্রিংয়ে রূপান্তর করা হচ্ছে


91

কেউ দয়া করে এমন একটি সাধারণ কোড পোস্ট করতে পারেন যা রূপান্তর করতে পারে,

System::String^

প্রতি,

সি ++ std::string

যেমন, আমি কেবল এর মান নির্ধারণ করতে চাই,

String^ originalString;

প্রতি,

std::string newString;

উত্তর:


39

পরীক্ষা করে দেখুন System::Runtime::InteropServices::Marshal::StringToCoTaskMemUni()এবং তার বন্ধুদের।

দুঃখিত এখন কোড পোস্ট করতে পারবেন না; পোস্ট করার আগে এই সংকলনটি পরীক্ষা করার জন্য আমার কাছে এই মেশিনে ভিএস নেই।


163

আপনার নিজের রোল করবেন না, মাইক্রোসফ্ট দ্বারা সরবরাহিত এই হ্যান্ডি (এবং এক্সটেনসিবল) র‍্যাপারগুলি ব্যবহার করুন।

উদাহরণ স্বরূপ:

#include <msclr\marshal_cppstd.h>

System::String^ managed = "test";
std::string unmanaged = msclr::interop::marshal_as<std::string>(managed);

4
এই দরকারী লিঙ্কটির জন্য THX, এই ইঙ্গিতটি আমাকে প্রচুর কোডিং করে সংরক্ষণ করেছে। একটি সাইড নোট হিসাবে: টেমপ্লেট / শ্রেণীর হয় #include <। msclr \ * জ> (যেমন #include <msclr \ marshal.h>) এবং msclr :: Interop নামস্থান দেখুন একটি এ উদাহরণে msdn.microsoft.com /de-de/library/vstudio/bb384859(v=vs.90).aspx )
Beachwalker

4
যদিও এটি সুবিধাজনক এটির মধ্যে পুরোপুরি যথাযথ এনকোডিং সমর্থন নেই। আমার এসও প্রশ্নটিও দেখুন: স্ট্যাকওভারফ্লো / প্রশ্ন / 18894551/… । আমার অনুমান যে মার্শাল_াস ইউনিকোড স্ট্রিংগুলিকে এসটিডি স্ট্রিংয়ে এসিপিতে রূপান্তরিত করে।
মাইক লিস্কে

এমএস সুপারিশটি হল মার্শাল_কন্টেক্সট ব্যবহার করা এবং রূপান্তরটি সম্পন্ন হওয়ার পরে এটি মুছুন। লিঙ্ক: msdn.microsoft.com/en-us/library/bb384856.aspx
রুসলান Makrenko

40

আপনি নিম্নলিখিত হিসাবে সহজেই এটি করতে পারেন

#include <msclr/marshal_cppstd.h>

System::String^ xyz="Hi boys"; 

std::string converted_xyz=msclr::interop::marshal_as< std::string >( xyz);

একটি সংক্ষিপ্ত এবং সাধারণ সমাধান এবং সাধারণ কাজের উদাহরণের জন্য +1 (যদিও আপনার কোডের শেষে একটি অতিরিক্ত প্রথম বন্ধনী রয়েছে)
সাইমন ফোর্সবার্গ

এটিই একমাত্র সমাধান যা সরাসরি প্রশ্নের উত্তর দেয়।
জিমিনিয়ন

8
হুম ... প্রায় একই কোডের প্রায় একই লাইনের সাথে 2 বছরেরও বেশি আগে ইতিমধ্যে দেওয়া উত্তরের জন্য 33 টি upvotes। যে জন্য অনেক পয়েন্ট অর্জন করার জন্য শ্রদ্ধা। ;-)
বিচওয়াক্কার

20

এটি আমার পক্ষে কাজ করেছে:

#include <stdlib.h>
#include <string.h>
#include <msclr\marshal_cppstd.h>
//..
using namespace msclr::interop;
//..
System::String^ clrString = (TextoDeBoton);
std::string stdString = marshal_as<std::string>(clrString); //String^ to std
//System::String^ myString = marshal_as<System::String^>(MyBasicStirng); //std to String^
prueba.CopyInfo(stdString); //MyMethod
//..
//Where: String^ = TextoDeBoton;
//and stdString is a "normal" string;

4
ইংরেজি অনুবাদ: "আমি এই পোস্টেও প্রতিক্রিয়া জানাতে চাই: পি। এটি আমার কাজ।"
শিববধু

9

সি ++ / ক্লাইপ প্রকল্পের জন্য আমি বেশ কয়েক বছর আগে লিখেছি এমন কিছু রূপান্তর রুটিনাম রয়েছে, তাদের এখনও কাজ করা উচিত

void StringToStlWString ( System::String const^ s, std::wstring& os)
    {
        String^ string = const_cast<String^>(s);
        const wchar_t* chars = reinterpret_cast<const wchar_t*>((Marshal::StringToHGlobalUni(string)).ToPointer());
        os = chars;
        Marshal::FreeHGlobal(IntPtr((void*)chars));

    }
    System::String^ StlWStringToString (std::wstring const& os) {
        String^ str = gcnew String(os.c_str());
        //String^ str = gcnew String("");
        return str;
    }

    System::String^ WPtrToString(wchar_t const* pData, int length) {
        if (length == 0) {
            //use null termination
            length = wcslen(pData);
            if (length == 0) {
                System::String^ ret = "";
                return ret;
            }
        }

        System::IntPtr bfr = System::IntPtr(const_cast<wchar_t*>(pData));
        System::String^ ret = System::Runtime::InteropServices::Marshal::PtrToStringUni(bfr, length);
        return ret;
    }

    void Utf8ToStlWString(char const* pUtfString, std::wstring& stlString) {
        //wchar_t* pString;
        MAKE_WIDEPTR_FROMUTF8(pString, pUtfString);
        stlString = pString;
    }

    void Utf8ToStlWStringN(char const* pUtfString, std::wstring& stlString, ULONG length) {
        //wchar_t* pString;
        MAKE_WIDEPTR_FROMUTF8N(pString, pUtfString, length);
        stlString = pString;
    }

@ অ্যালাপ, সিস্টেম ব্যবহার করুন :: রানটাইম :: ইন্টারপ সার্ভিস :: মার্শাল বা নেমস্পেস সিস্টেম ব্যবহার করে লেখুন :: রানটাইম :: ইন্টারপ সার্ভিস;
নিও

6

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

void MarshalString ( String ^ s, string& os ) {
   using namespace Runtime::InteropServices;
   const char* chars = 
      (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
   os = chars;
   Marshal::FreeHGlobal(IntPtr((void*)chars));
}

//this is the code to use the function:
scheduleBox->SetSelected(0,true);
string a = "test";
String ^ c = gcnew String(scheduleBox->SelectedItem->ToString());
MarshalString(c, a);
filestream << a;

এবং এখানে উদাহরণ সহ এমএসডিএন পৃষ্ঠা রয়েছে: http://msdn.microsoft.com/en-us/library/1b4az623(v=vs.80).aspx

আমি জানি এটি একটি খুব সহজ সমাধান তবে এটি আমাকে সমস্যার সমাধানের সময় এবং বেশিরভাগ ফোরাম পরিদর্শন করেছে যা শেষ পর্যন্ত কাজ করেছে something


6

আমি স্ট্রিং from থেকে স্টাডি :: স্ট্রিংয়ের একটি সহজ উপায় পেয়েছি স্প্রিন্টফ () ব্যবহার করা।

char cStr[50] = { 0 };
String^ clrString = "Hello";
if (clrString->Length < sizeof(cStr))
  sprintf(cStr, "%s", clrString);
std::string stlString(cStr);

মার্শাল ফাংশন কল করার দরকার নেই!

আপডেট আপডেট এরিকের জন্য, আমি বাফার ওভারফ্লো প্রতিরোধে ইনপুট স্ট্রিংয়ের আকারটি পরীক্ষা করতে স্যাম্পল কোডটি পরিবর্তন করেছি।


4
বিশেষত মার্শাল স্ট্রিংয়ের জন্য বিশেষভাবে ডিজাইন করা ফাংশনগুলি কল করা এড়াতে আপনার কোডে একটি বাফার ওভারফ্লো দুর্বলতার পরিচয় দেওয়ার জন্য এটি একটি কৌতূহলপূর্ণ সিদ্ধান্ত।
এরিক

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

@ এরিক অভ্যন্তরীণভাবে এটি আপনার জন্য মার্শাল করছে। বিশদ জন্য এই এসও উত্তর দেখুন । আপনি যদি আগেই আকারটি যাচাই করেন তবে আপনার কোনও ওভারফ্লো সমস্যা হবে না এবং কোডটি আরও পরিষ্কার।
আইওনিয়ান 1616

4

সি # তার স্ট্রিংয়ের জন্য ইউটিএফ 16 ফর্ম্যাট ব্যবহার করে।
সুতরাং, কেবল ধরণের রূপান্তরিত করার পাশাপাশি, আপনার স্ট্রিংয়ের আসল বিন্যাস সম্পর্কেও সচেতন হওয়া উচিত।

জন্য কম্পাইল মাল্টি বাইট ক্যারেক্টার সেট ভিসুয়াল স্টুডিও এবং উইন এপিআই UTF8 হওয়া অনুমান (আসলে যা এনকোডিং উইন্ডোজ উইন্ডোজ 28591 )।
যখন ইউনিকোড চরিত্র সেট করার জন্য ভিজ্যুয়াল স্টুডিও এবং উইন এপিআই ইউটিএফ 16 ধরে নেয়।

সুতরাং, আপনাকে অবশ্যই স্ট্রিংটি ইউটিএফ 16 থেকে ইউটিএফ 8 ফর্ম্যাটে রূপান্তর করতে হবে, এবং কেবল এসডিডি স্ট্রিংতে রূপান্তর করতে হবে না।
কিছু নন-ল্যাটিন ভাষার মতো মাল্টি-ক্যারেক্টার ফর্ম্যাটগুলির সাথে কাজ করার সময় এটি প্রয়োজনীয় হয়ে উঠবে।

ধারণাটি স্থির হয় যে std::wstring সর্বদা UTF16 প্রতিনিধিত্ব করে
এবং std::string সর্বদা ইউটিএফ 8 প্রতিনিধিত্ব করে ।

এটি সংকলক দ্বারা প্রয়োগ করা হয়নি, এটির জন্য আরও ভাল নীতি রয়েছে।

#include "stdafx.h"
#include <string>
#include <codecvt>
#include <msclr\marshal_cppstd.h>

using namespace System;

int main(array<System::String ^> ^args)
{
    System::String^ managedString = "test";

    msclr::interop::marshal_context context;

    //Actual format is UTF16, so represent as wstring
    std::wstring utf16NativeString = context.marshal_as<std::wstring>(managedString); 

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(utf16NativeString);

    return 0;
}

বা এটি আরও কমপ্যাক্ট বাক্য গঠনতে রাখুন:

int main(array<System::String ^> ^args)
{
    System::String^ managedString = "test";

    msclr::interop::marshal_context context;
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    std::string utf8NativeString = convert.to_bytes(context.marshal_as<std::wstring>(managedString));

    return 0;
}

4
আমি কেবল আমার ব্যবহারের ক্ষেত্রে ইউটিএফ 8 তে রূপান্তর করার গুরুত্বের উপর জোর দিতে চাই: আমাকে উইন 32 ওপেনফাইলডায়লগ থেকে প্রাপ্ত একটি ফাইল পাথ (যেখানে মাল্টিবাইট অক্ষরযুক্ত ফাইলের নামগুলি সম্ভব, উদাহরণস্বরূপ এশিয়ান অক্ষরযুক্ত ফাইলের নাম) একটি স্ট্যান্ডের মাধ্যমে ইঞ্জিন কোডে পাস করতে হবে :: স্ট্রিং, সুতরাং ইউটিএফ 8 তে রূপান্তরটি অতীব গুরুত্বপূর্ণ ছিল। চমৎকার উত্তরের জন্য ধন্যবাদ!
জেসন ম্যাকক্লিনসি

0

আমি মার্শালার থেকে দূরে থাকতে পছন্দ করি।

Using CString newString(originalString);

আমার কাছে অনেক পরিষ্কার এবং দ্রুত বলে মনে হচ্ছে। কোনও প্রসঙ্গ তৈরি এবং মুছে ফেলার বিষয়ে চিন্তা করার দরকার নেই।


0

// আমি কোডটি নীচে লিখতে ভিএস ২০১২ ব্যবহার করেছি - রূপান্তর_ সিস্টেম_ স্ট্রিংটিকে স্ট্যান্ডার্ড_সটিংয়ে রূপান্তর করি

        #include "stdafx.h"
        #include <iostream>
        #include <string> 

        using namespace System;
        using namespace Runtime::InteropServices; 


        void MarshalString ( String^ s, std::string& outputstring )
        {  
           const char* kPtoC =  (const char*) (Marshal::StringToHGlobalAnsi(s)).ToPointer();                                                        
           outputstring = kPtoC;  
           Marshal::FreeHGlobal(IntPtr((void*)kPtoC));  
        }   

        int _tmain(int argc, _TCHAR* argv[])
        {
             std::string strNativeString;  
             String ^ strManagedString = "Temp";

             MarshalString(strManagedString, strNativeString);  
             std::cout << strNativeString << std::endl; 

             return 0;
        }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.