ฉันจะแปลง double เป็นสตริงใน C ++ ได้อย่างไร


171

ฉันต้องการเก็บ double เป็นสตริง ฉันรู้ว่าฉันสามารถใช้งานได้printfถ้าฉันต้องการแสดง แต่ฉันต้องการเก็บไว้ในตัวแปรสตริงเพื่อที่ฉันจะสามารถเก็บไว้ในแผนที่ได้ในภายหลัง (ตามค่าไม่ใช่กุญแจ )


2
คำถามที่จะตอบคำถามของคุณ: ทำไมคุณถึงเก็บค่าสองค่าในสตริงเพื่อเก็บไว้ในแผนที่? คุณจะใช้ string-ified double เป็นคีย์หรือไม่? ถ้าไม่ทำไมไม่ปล่อยให้เป็นสองเท่า
Matt McClellan

1
จุดที่น่าสนใจ อย่างไรก็ตามการใช้ double เป็นคีย์แผนที่อาจจะเต็มไปด้วยอันตรายอย่างไรก็ตามเนื่องจากการเปรียบเทียบที่แน่นอนเกี่ยวกับค่าจุดลอยตัวคือ การจัดทำดัชนีการแทนค่าสตริงจะช่วยหลีกเลี่ยงปัญหา
Fred Larson

2
ทำไมแปลงเลย? เก็บไว้ในแผนที่เป็นสองเท่าและหลีกเลี่ยงการแปลงเป็นและจาก
EvilTeach

3
ที่ยังคงเสียงเหมือนการโทรหาวัตถุ สหภาพจะทำงาน แต่ละวัตถุจะแทรกค่าต่าง ๆ ลงไปและให้มันตรวจสอบตัวเอง
EvilTeach

2
ฉันมีพวงชื่อ / ค่าคู่ในไฟล์ มันไม่เรียกหาวัตถุ
Bill the Lizard

คำตอบ:


183

วิธีเพิ่ม (tm) :

std::string str = boost::lexical_cast<std::string>(dbl);

วิธีC ++ มาตรฐาน :

std::ostringstream strs;
strs << dbl;
std::string str = strs.str();

หมายเหตุ : อย่าลืม#include <sstream>


3
ฉันคิดว่าการเพิ่ม :: lexical_cast สวยมากเป็นวิธีมาตรฐาน C ++ เพียงแค่บรรจุอย่างดีสำหรับคุณ BTW, litb คุณพิมพ์ผิดเล็กน้อย - "boot: lexical_cast"
Fred Larson

2
เพิ่ม :: lexical_cast ไม่ได้เป็นเพียง wrapper ง่าย ๆ รอบ ๆ รหัส stringstream รูทีนการแปลงจำนวนมากถูกนำมาใช้แบบอินไลน์ ตามการวัดประสิทธิภาพที่ด้านล่างของหน้านี้ ( boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htm ) การเพิ่ม :: lexical_cast เร็วกว่าการใช้ stringstreams และในกรณีส่วนใหญ่เร็วกว่า scanf / printf
Ferruccio

1
@ เฟอร์ใครบอกว่ามันเป็นเสื้อคลุมเรียบง่าย? และขอบคุณที่ให้ลิงค์ฉันคิดว่าจริง ๆ แล้วมันเป็นเสื้อคลุมที่เรียบง่ายไม่มากก็น้อย :)
โยฮันเนส Schaub - litb

27
อย่าลืม#include <sstream>วิธี c ++ :)
VladL

3
หากคุณไม่มีเอกสาร#include <sstream>คุณจะได้รับข้อผิดพลาด "ไม่อนุญาตประเภทที่ไม่สมบูรณ์"
เทรเวอร์ซัลลิแวน

194
// The C way:
char buffer[32];
snprintf(buffer, sizeof(buffer), "%g", myDoubleVar);

// The C++03 way:
std::ostringstream sstream;
sstream << myDoubleVar;
std::string varAsString = sstream.str();

// The C++11 way:
std::string varAsString = std::to_string(myDoubleVar);

// The boost way:
std::string varAsString = boost::lexical_cast<std::string>(myDoubleVar);

1
c ++ วิธีการของคุณจะไม่ทำงานเพราะoperator <<ผลตอบแทนมากกว่าstd::ostream& stringstream&
Konrad Rudolph

ดูเหมือนว่าสายน้ำของฉันจะออกแรงเป็นสนิมฉันชอบวิธี ol 'C แก้ไขแล้ว (ฉันหวังว่า)
Adam Rosenfield

รหัส C ของคุณทำให้ฉันผิดหวังในตอนแรก ฉันยังคงสนับสนุนคุณในการให้ทางเลือกที่ถูกต้อง
Bill the Lizard

2
upvote สำหรับการรวมวิธี C ดูเหมือนว่าฉันจะสะอาดกว่ามาก
Nealon

11
โหวตขึ้นสำหรับวิธี C ++ 11 ฉันใหม่กับ C ++ และไม่ทราบว่ามีto_stringฟังก์ชั่น ฉันใช้ Microsoft Visual C ++ 2013
Trevor Sullivan

123

วิธีมาตรฐาน C ++ 11 (หากคุณไม่สนใจรูปแบบผลลัพธ์):

#include <string>

auto str = std::to_string(42.5); 

to_stringเป็นฟังก์ชันไลบรารีใหม่ที่นำมาใช้ในN1803 (r0), N1982 (r1) และN2408 (r2) " Simple Numeric Access " นอกจากนี้ยังมีstodฟังก์ชั่นเพื่อทำการย้อนกลับ

หากคุณต้องการมีรูปแบบผลลัพธ์ที่แตกต่างจาก"%f"ใช้snprintfหรือostringstreamวิธีการตามที่แสดงในคำตอบอื่น ๆ


3
ใช่เลยที่รัก. to_string และ stod ทั้งสองทำงานใน Visual Studio 11
BSalita

โอ้ที่รัก ... to_string ดูเหมือนจะไม่ทำงานใน VisualStudio 2010): นั่นหรือฉันไม่รู้ว่าฉันกำลังทำอะไร (เป็นไปได้มาก)
chessofnerd

1
ควรสูงกว่านี้เพราะมันทันสมัยกว่า!
gsamaras

1
มีวิธีใดที่จะทำให้ฟังก์ชั่นนี้ไม่เพิ่มทศนิยมมากกว่าที่ต้องการหรือไม่? เมื่อฉันแปลงดับเบิล8.0มันให้สตริง"8.000000"ในขณะที่"8"จะดีอย่างสมบูรณ์
HelloGoodbye

1
นี้ไม่ได้ผลสำหรับตัวเลขเล็ก ๆ ... เช่น: 1e-9ผลิต0.000000
user3728501

24

ถ้าคุณใช้ภาษา C ++, sprintfหลีกเลี่ยง มันไม่ได้ใช้ภาษา C ++ และมีปัญหาหลายอย่าง Stringstreams เป็นวิธีการที่เลือกห่อหุ้มโดยเฉพาะอย่างยิ่งในBoost.LexicalCastซึ่งสามารถทำได้ค่อนข้างง่าย:

template <typename T>
std::string to_string(T const& value) {
    stringstream sstr;
    sstr << value;
    return sstr.str();
}

การใช้งาน:

string s = to_string(42.5);

24

คุณสามารถใช้std :: to_stringใน C ++ 11

double d = 3.0;
std::string str = std::to_string(d);

ตัวเลขของฉันเล็กมากและstd::to_string()เพิ่งคืนมา 0.000000 และไม่ใช่ในรูปแบบทางวิทยาศาสตร์
erfan

11

sprintfไม่เป็นไร แต่ใน C ++ วิธีที่ดีกว่าปลอดภัยกว่าและช้ากว่าเล็กน้อยคือการแปลงstringstream:

#include <sstream>
#include <string>

// In some function:
double d = 453.23;
std::ostringstream os;
os << d;
std::string str = os.str();

คุณยังสามารถใช้Boost.LexicalCast :

#include <boost/lexical_cast.hpp>
#include <string>

// In some function:
double d = 453.23;
std::string str = boost::lexical_cast<string>(d);

ในทั้งสองกรณีstrควรจะ"453.23"หลังจากนั้น LexicalCast มีข้อได้เปรียบบางประการที่ทำให้มั่นใจว่าการแปลงจะเสร็จสมบูรณ์ มันใช้stringstreamภายใน


10

ฉันจะมองไปที่C ++ String Toolkit ไลบรารี เพิ่งโพสต์คำตอบที่คล้ายกันที่อื่น ฉันพบว่ามันรวดเร็วและเชื่อถือได้

#include <strtk.hpp>

double pi = M_PI;
std::string pi_as_string  = strtk::type_to_string<double>( pi );

7

Sutter สมุนไพรมีดีบทความเกี่ยวกับการจัดรูปแบบสตริง ฉันแนะนำให้อ่าน ฉันเคยเชื่อมโยงมันมาก่อนดังนั้น


1
นี่ไม่ใช่คำตอบ แต่จะแสดงความคิดเห็นที่มีประโยชน์มากกับคำถาม
การชดเชย จำกัด

6

ปัญหาของ lexical_cast คือการไม่สามารถกำหนดความแม่นยำได้ โดยปกติถ้าคุณแปลงคู่เป็นสตริงเป็นเพราะคุณต้องการพิมพ์ออกมา หากความแม่นยำมีมากหรือน้อยเกินไปก็จะส่งผลต่อผลลัพธ์ของคุณ



4

เฮ้ฉันเพิ่งเขียนสิ่งนี้ (ไม่เกี่ยวข้องกับคำถามนี้):

string temp = "";
stringstream outStream;
double ratio = (currentImage->width*1.0f)/currentImage->height;
outStream << " R: " << ratio;
temp = outStream.str();

/* rest of the code */

2

คุณอาจต้องการอ่านโพสต์ก่อนหน้าของฉันใน SO (รุ่น Macro'ed ที่มีวัตถุ ostringstream ชั่วคราว)

สำหรับบันทึก: ในรหัสของฉันฉันชอบ snprintf () ด้วยอาเรย์ถ่านบนสแต็คท้องถิ่นมันไม่มีประสิทธิภาพ (เอาละบางทีถ้าคุณมีขนาดใหญ่เกินขนาดและวนซ้ำเพื่อทำสอง ...

(ฉันยังห่อมันด้วย vsnprintf () แต่นั่นทำให้ฉันต้องใช้การตรวจสอบบางอย่าง Yelp ถ้าคุณต้องการรหัส ... )


2

ลองดูที่sprintf()และครอบครัว


2
ฉันพูดถึง printf เพราะ googling เปิดบทความมากมายที่พูดว่าแปลงจาก double เป็น string ที่คุณใช้ printf พวกเขาตั้งสมมติฐานว่าสิ่งเดียวที่คุณสามารถทำได้คือการพิมพ์ซึ่งในกรณีของฉันเป็นเท็จ
Bill the Lizard

ทำไมคุณถึงลงคะแนน -1? ฉันคิดว่า sprintf นั้นดี @BilltheLizard sprint พิมพ์บางสิ่งบางอย่างไปยังหน้าจอ char * ไม่ใช่ มีคนตอบว่าวิธี c ยังคงได้รับคะแนนเสียงจำนวนมาก
worldterminator

2

Normaly สำหรับการดำเนินการนี้คุณต้องใช้ฟังก์ชัน ecvt, fcvt หรือ gcvt:

/* gcvt example */
#include <stdio.h>
#include <stdlib.h>

main ()
{
  char buffer [20];
  gcvt (1365.249,6,buffer);
  puts (buffer);
  gcvt (1365.249,3,buffer);
  puts (buffer);
  return 0;
}

Output:
1365.25
1.37e+003   

ในฐานะที่เป็นฟังก์ชั่น:

void double_to_char(double f,char * buffer){
  gcvt(f,10,buffer);
}

0

คุณสามารถลองสไตล์ที่กะทัดรัดยิ่งขึ้น:

std::string number_in_string;

double number_in_double;

std::ostringstream output;

number_in_string = (dynamic_cast< std::ostringstream*>(&(output << number_in_double <<

std::endl)))->str(); 

0

to_string()ใช้
ตัวอย่าง:

#include <iostream>   
#include <string>  

using namespace std;
int main ()
{
    string pi = "pi is " + to_string(3.1415926);
    cout<< "pi = "<< pi << endl;

  return 0;
}

รันด้วยตัวคุณเอง: http://ideone.com/7ejfaU สิ่ง
เหล่านี้มีให้ใช้เช่นกัน:

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);

0

คุณสามารถแปลงอะไรเป็นอะไรก็ได้โดยใช้ฟังก์ชั่นนี้:

template<class T = std::string, class U>
T to(U a) {
    std::stringstream ss;
    T ret;
    ss << a;
    ss >> ret;
    return ret;
};

การใช้งาน:

std::string str = to(2.5);
double d = to<double>("2.5");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.