بديل لـ itoa() لتحويل عدد صحيح إلى سلسلة C++؟[ينسخ]

StackOverflow https://stackoverflow.com/questions/228005

  •  03-07-2019
  •  | 
  •  

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

كنت أتساءل إذا كان هناك بديل ل itoa() لتحويل عدد صحيح إلى سلسلة لأنه عندما أقوم بتشغيله في Visual Studio أحصل على تحذيرات، وعندما أحاول إنشاء برنامجي على Linux، أحصل على خطأ في الترجمة.

هل كانت مفيدة؟

المحلول

في C++ 11 يمكنك استخدام std::to_string:

#include <string>

std::string s = std::to_string(5);

إذا كنت تعمل مع الإصدار السابق لـ C++ 11، فيمكنك استخدام تدفقات C++:

#include <sstream>

int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();

مأخوذ من http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/

نصائح أخرى

دفعة::lexical_cast يعمل بشكل جيد.

#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
    std::string foo = boost::lexical_cast<std::string>(argc);
}

علم الآثار

كانت itoa وظيفة مساعدة غير قياسية مصممة لاستكمال وظيفة atoi القياسية، وربما تخفي sprintf (يمكن تنفيذ معظم ميزاتها من حيث sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html

الطريق سي

استخدم سبرينتف.أو snprintf.أو أي أداة تجدها

على الرغم من حقيقة أن بعض الوظائف ليست في المعيار، كما ذكر بحق "onebyone" في أحد تعليقاته، فإن معظم المترجمين سيقدمون لك بديلاً (على سبيل المثال.يحتوي Visual C++ على _snprintf الخاص به والذي يمكنك كتابته إلى snprintf إذا كنت في حاجة إليه).

طريقة C++.

استخدم تدفقات C++ (في الحالة الحالية std::stringstream (أو حتى std::strstream المهملة، كما اقترحها Herb Sutter في أحد كتبه، لأنه أسرع إلى حد ما).

خاتمة

أنت تستخدم لغة C++، مما يعني أنه يمكنك اختيار الطريقة التي تريدها:

  • الطريقة الأسرع (أي.(طريقة C)، ولكن يجب أن تتأكد من أن الكود يمثل عنق الزجاجة في تطبيقك (التحسينات المبكرة شريرة، وما إلى ذلك) وأن الكود الخاص بك مغلف بأمان لتجنب المخاطرة بتجاوز المخزن المؤقت.

  • الطريقة الأكثر أمانًا (أي طريقة C++)، إذا كنت تعلم أن هذا الجزء من الكود ليس مهمًا، لذا تأكد من أن هذا الجزء من الكود لن ينكسر في لحظات عشوائية لأن شخصًا ما أخطأ في الحجم أو المؤشر (وهو ما يحدث في الحياة الحقيقية، مثل...بالأمس، على جهاز الكمبيوتر الخاص بي، لأن أحدهم اعتقد أنه من "الرائع" استخدام الطريقة الأسرع دون الحاجة إليها حقًا).

جرب sprintf ():

char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"

sprintf() يشبه printf() ولكنه يُخرج إلى سلسلة.

أيضًا، كما ذكر Parappa في التعليقات، قد ترغب في استخدام snprintf() لإيقاف حدوث تجاوز سعة المخزن المؤقت (حيث لا يتناسب الرقم الذي تقوم بتحويله مع حجم السلسلة الخاصة بك.) وهو يعمل على النحو التالي:

snprintf(str, sizeof(str), "%d", num);

وراء الكواليس، يقوم lexical_cast بما يلي:

std::stringstream str;
str << myint;
std::string result;
str >> result;

إذا كنت لا ترغب في "سحب" التعزيز لهذا الغرض، فإن استخدام ما سبق يعد حلاً جيدًا.

يمكننا تحديد منطقتنا iota وظيفة في C++ على النحو التالي:

string itoa(int a)
{
    string ss="";   //create empty string
    while(a)
    {
        int x=a%10;
        a/=10;
        char i='0';
        i=i+x;
        ss=i+ss;      //append new character at the front of the string!
    }
    return ss;
}

لا تنسى أن #include <string>.

С++11 يحل هذا العرض أخيرًا std::to_string.أيضًا boost::lexical_cast هي أداة مفيدة للمترجمين الأقدم.

أستخدم هذه القوالب

template <typename T> string toStr(T tmp)
{
    ostringstream out;
    out << tmp;
    return out.str();
}


template <typename T> T strTo(string tmp)
{
    T output;
    istringstream in(tmp);
    in >> output;
    return output;
}

يحاول Boost.Format أو تنسيق سريع, ، مكتبات C++ عالية الجودة:

int i = 10;
std::string result;

مع Boost.Format

result = str(boost::format("%1%", i));

أو التنسيق السريع

fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);

من الواضح أن كلاهما يقوم بأكثر من مجرد تحويل بسيط لعدد صحيح واحد

يمكنك بالفعل تحويل أي شيء إلى سلسلة باستخدام وظيفة قالب واحدة مكتوبة بذكاء.يستخدم مثال التعليمات البرمجية هذا حلقة لإنشاء أدلة فرعية في نظام Win-32.يتم استخدام عامل تسلسل السلسلة، عامل التشغيل+، لتسلسل جذر بلاحقة لإنشاء أسماء الدليل.يتم إنشاء اللاحقة عن طريق تحويل متغير التحكم في الحلقة، i، إلى سلسلة C++، باستخدام وظيفة القالب، وتسلسل ذلك بسلسلة أخرى.

//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology

#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>

using namespace std;

string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an   */
/* integer as input and as output,    */
/* returns a C++ string.              */
/* itoa()  returned a C-string (null- */
/* terminated)                        */
/* This function is not needed because*/
/* the following template function    */
/* does it all                        */
/**************************************/   
       string r;
       stringstream s;

       s << x;
       r = s.str();

       return r;

}

template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of   */
/* C++ templates. This function will  */
/* convert anything to a string!      */
/* Precondition:                      */
/* operator<< is defined for type T    */
/**************************************/
       string r;
       stringstream s;

       s << argument;
       r = s.str();

       return r;

}

int main( )
{
    string s;

    cout << "What directory would you like me to make?";

    cin >> s;

    try
    {
      mkdir(s.c_str());
    }
    catch (exception& e) 
    {
      cerr << e.what( ) << endl;
    }

    chdir(s.c_str());

    //Using a loop and string concatenation to make several sub-directories
    for(int i = 0; i < 10; i++)
    {
        s = "Dir_";
        s = s + toString(i);
        mkdir(s.c_str());
    }
    system("PAUSE");
    return EXIT_SUCCESS;
}

قم بتخصيص سلسلة ذات طول كافٍ، ثم استخدم snprintf.

أفضل إجابة، IMO، هي الوظيفة المتوفرة هنا:

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

إنه يحاكي الوظيفة غير التابعة لـ ANSI التي توفرها العديد من libs.

char* itoa(int value, char* result, int base);

كما أنه سريع للغاية ويتم تحسينه بشكل جيد تحت -O3، وسبب عدم استخدامك لـ c++ string_format() ...أو sprintf هو أنها بطيئة جدا، أليس كذلك؟

لاحظ أن جميع stringstream طُرق يمكن تتضمن تأمين استخدام الكائن المحلي للتنسيق.هذا يمكن كن شيئًا يجب الحذر منه إذا كنت تستخدم هذا التحويل من عدة سلاسل رسائل...

انظر هنا للمزيد. تحويل رقم إلى سلسلة ذات طول محدد في C++

int number = 123;

stringstream = s;

s << number;

cout << ss.str() << endl;

إذا كنت مهتمًا بطريقة سريعة وآمنة لتحويل الأعداد الصحيحة إلى سلسلة ولا تقتصر على المكتبة القياسية، فيمكنني أن أوصي بـ FormatInt الطريقة من تنسيق سي++ مكتبة:

fmt::FormatInt(42).str();   // convert to std::string
fmt::FormatInt(42).c_str(); // convert and get as a C string
                            // (mind the lifetime, same as std::string::c_str())

بحسب ال عدد صحيح لمعايير تحويل السلسلة من Boost Karma، هذه الطريقة أسرع عدة مرات من طريقة glibc sprintf أو std::stringstream.إنه أسرع من Boost Karma int_generator كما تم تأكيد ذلك من قبل معيار مستقل.

تنصل:أنا مؤلف هذه المكتبة.

انا كتبت هذا آمن للخيط وظيفة منذ بعض الوقت، وأنا سعيد جدًا بالنتائج وأشعر أن الخوارزمية خفيفة الوزن وبسيطة، مع أداء يبلغ حوالي 3 أضعاف وظيفة MSVC _itoa() القياسية.

إليك الرابط. الأمثل Base-10 وظيفة itoa () فقط؟ الأداء لا يقل عن 10 أضعاف أداء sprintf ().المعيار هو أيضًا اختبار ضمان الجودة للوظيفة، كما يلي.

start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
    if (i != atoi(_i32toa(buff, (int32_t)i))) {
        printf("\nError for %i", i);
    }
    if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));

هناك بعض الاقتراحات السخيفة التي تم تقديمها حول استخدام مساحة تخزين المتصل والتي من شأنها أن تترك النتيجة عائمة في مكان ما في مخزن مؤقت في مساحة عنوان المتصل.تجاهلهم.الكود الذي أدرجته يعمل بشكل مثالي، كما يوضح رمز المعيار/QA.

أعتقد أن هذا الرمز بسيط بدرجة كافية لاستخدامه في بيئة مضمنة.YMMV، بطبيعة الحال.

على الأنظمة الأساسية المشتقة من Windows CE، لا توجد iostreamق افتراضيا.طريقة الذهاب إلى هناك هي المفضلة مع _itoa<> الأسرة، عادة _itow<> (نظرًا لأن معظم عناصر السلسلة موجودة في Unicode على أي حال).

معظم الاقتراحات المذكورة أعلاه من الناحية الفنية ليست لغة C++، بل هي حلول لغة C.

النظر في استخدام الأمراض المنقولة جنسيا :: سلسلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top