คุณจะแปลง float เป็นสตริงใน C ++ ได้อย่างไรในขณะที่ระบุความแม่นยำและจำนวนหลักทศนิยม
ตัวอย่างเช่น: 3.14159265359 -> "3.14"
คุณจะแปลง float เป็นสตริงใน C ++ ได้อย่างไรในขณะที่ระบุความแม่นยำและจำนวนหลักทศนิยม
ตัวอย่างเช่น: 3.14159265359 -> "3.14"
คำตอบ:
วิธีทั่วไปคือการใช้stringstream
:
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
ดูคงที่
ใช้สัญกรณ์ทศนิยมคงที่
ตั้ง
floatfield
ธงรูปแบบสำหรับSTRfixed
กระแสไปเมื่อ
floatfield
ตั้งค่าเป็นค่าfixed
ทศนิยมจะถูกเขียนโดยใช้สัญกรณ์จุดคงที่: ค่าจะแสดงด้วยตัวเลขจำนวนมากในส่วนทศนิยมตามที่ระบุโดยฟิลด์ความแม่นยำ (precision
) และไม่มีส่วนเลขชี้กำลัง
สำหรับการแปลงวัตถุประสงค์ทางเทคนิคเช่นการจัดเก็บข้อมูลในไฟล์ XML หรือ JSON C ++ 17 จะกำหนดกลุ่มฟังก์ชันto_chars
สมมติว่าคอมไพเลอร์ที่เข้ากันได้ (ซึ่งเราขาดในขณะที่เขียน) สิ่งนี้สามารถพิจารณาได้:
#include <array>
#include <charconv>
double pi = 3.14159265359;
std::array<char, 128> buffer;
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi,
std::chars_format::fixed, 2);
if (ec == std::errc{}) {
std::string s(buffer.data(), ptr);
// ....
}
else {
// error handling
}
วิธีการทั่วไปสำหรับการทำสิ่งนี้คือ "พิมพ์เป็นสตริง" ใน C ++ หมายถึงการใช้std::stringstream
สิ่งต่างๆเช่น:
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
อีกทางเลือกหนึ่งคือsnprintf
:
double pi = 3.1415926;
std::string s(16, '\0');
auto written = std::snprintf(&s[0], s.size(), "%.2f", pi);
s.resize(written);
snprintf
ดีกว่าในกรณีนี้? กรุณาอธิบาย ... มันจะไม่เร็วขึ้นอย่างแน่นอนสร้างโค้ดน้อยลง [ฉันเขียนการใช้งาน printf มันค่อนข้างกะทัดรัดที่โค้ดต่ำกว่า 2,000 บรรทัด แต่การขยายมาโครจะอยู่ที่ประมาณ 2,500 บรรทัด]
__printf_fp
ฟังก์ชันพื้นฐานเดียวกัน- ค่อนข้างแปลกที่ต้องใช้เวลานานกว่านี้มากstringstream
เพราะไม่ควรต้อง
คุณสามารถใช้ C ++ 20 std::format
หรือfmt::format
ฟังก์ชันจากไลบรารี {fmt} ได้โดยstd::format
ขึ้นอยู่กับ:
#include <fmt/core.h>
int main()
std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}
ที่2
เป็นความแม่นยำ
นี่คือวิธีแก้ปัญหาโดยใช้มาตรฐานเท่านั้น อย่างไรก็ตามโปรดทราบว่านี่เป็นเพียงการปัดเศษเท่านั้น
float number = 3.14159;
std::string num_text = std::to_string(number);
std::string rounded = num_text.substr(0, num_text.find(".")+3);
เพื่อrounded
ให้ผลตอบแทน:
3.14
โค้ดจะแปลง float ทั้งหมดเป็นสตริง แต่จะตัดอักขระทั้งหมด 2 ตัวต่อท้าย "."
number + 0.005
ในกรณีของฉัน
ที่นี่ฉันกำลังให้ตัวอย่างเชิงลบที่คุณต้องการหลีกเลี่ยงเมื่อแปลงตัวเลขลอยเป็นสตริง
float num=99.463;
float tmp1=round(num*1000);
float tmp2=tmp1/1000;
cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;
คุณได้รับ
99463 99.463 99.462997
หมายเหตุ: ตัวแปร num อาจเป็นค่าใดก็ได้ที่ใกล้เคียงกับ 99.463 คุณจะได้รับงานพิมพ์เดียวกัน ประเด็นคือหลีกเลี่ยงฟังก์ชัน c ++ 11 "to_string" ที่สะดวก ฉันใช้เวลาสักพักในการออกจากกับดักนี้ วิธีที่ดีที่สุดคือวิธี stringstream และ sprintf (ภาษา C) C ++ 11 หรือใหม่กว่าควรระบุพารามิเตอร์ที่สองเป็นจำนวนหลักหลังจุดลอยตัวที่จะแสดง ตอนนี้ค่าเริ่มต้นคือ 6 ฉันกำลังวางสิ่งนี้เพื่อไม่ให้คนอื่นเสียเวลากับเรื่องนี้
ฉันเขียนเวอร์ชันแรกของฉันโปรดแจ้งให้เราทราบหากคุณพบข้อบกพร่องใด ๆ ที่ต้องได้รับการแก้ไข คุณสามารถควบคุมพฤติกรรมที่แน่นอนได้ด้วย iomanipulator ฟังก์ชันของฉันมีไว้สำหรับแสดงจำนวนหลักหลังจุดทศนิยม
string ftos(float f, int nd) {
ostringstream ostr;
int tens = stoi("1" + string(nd, '0'));
ostr << round(f*tens)/tens;
return ostr.str();
}