Làm cách nào để chuyển đổi một chuỗi thành một chuỗi trong C ++?


171

Tôi cần lưu trữ gấp đôi như một chuỗi. Tôi biết tôi có thể sử dụng printfnếu tôi muốn hiển thị nó, nhưng tôi chỉ muốn lưu trữ nó trong một biến chuỗi để tôi có thể lưu trữ nó trong bản đồ sau này (dưới dạng giá trị , không phải là khóa ).


2
Một câu hỏi để trả lời câu hỏi của bạn: tại sao bạn lưu trữ giá trị kép trong một chuỗi để lưu trữ nó trong bản đồ? Bạn có định sử dụng chuỗi nhân đôi chuỗi làm khóa không? Nếu không, tại sao không để lại gấp đôi như vậy?
Matt McClellan

1
Điểm thú vị. Tuy nhiên, việc sử dụng gấp đôi làm khóa bản đồ có thể gây ra nguy hiểm, vì luôn luôn so sánh chính xác các giá trị của dấu phẩy động. Lập chỉ mục trên một đại diện chuỗi tránh vấn đề.
Fred Larson

2
Tại sao lại chuyển đổi nó? Lưu trữ nó trong bản đồ dưới dạng gấp đôi và tránh chuyển đổi sang và từ.
EvilTeach

3
Điều đó vẫn giống như một cuộc gọi cho các đối tượng. Một công đoàn sẽ làm việc. Mỗi đối tượng để chèn các giá trị khác nhau vào nó và tự xác thực nó.
EvilTeach

2
Tôi chỉ có một loạt các cặp tên / giá trị trong một tập tin. Nó không gọi cho các đối tượng.
Bill Lizard

Câu trả lời:


183

Cách tăng (tm) :

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

Cách tiêu chuẩn C ++ :

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

Lưu ý : Đừng quên#include <sstream>


3
Tôi nghĩ boost :: lexical_cast khá nhiều theo cách C ++ tiêu chuẩn, chỉ được đóng gói độc đáo cho bạn. BTW, litb, bạn có một lỗi đánh máy nhỏ trong đó - "boot: lexical_cast".
Fred Larson

2
boost :: lexical_cast không chỉ là một trình bao bọc đơn giản xung quanh mã chuỗi. Nhiều thói quen chuyển đổi được thực hiện nội tuyến. Theo các phép đo hiệu suất ở dưới cùng của trang này ( boost.org/doc/libs/1_47_0/libs/conversion/lexical_cast.htmlm ), boost :: lexical_cast nhanh hơn so với sử dụng chuỗi dòng và, trong hầu hết các trường hợp, nhanh hơn scanf / printf
Ferruccio

1
@Ferr ai nói đó là một gói đơn giản? Và cảm ơn vì đã cung cấp liên kết, tôi thực sự đã nghĩ rằng nó ít nhiều là một trình bao bọc đơn giản :)
Johannes Schaub - litb

27
đừng quên #include <sstream>theo cách của c ++ :)
VladL

3
Vì lợi ích của tài liệu, nếu bạn không #include <sstream>, bạn sẽ gặp lỗi "loại không đầy đủ không được phép."
Trevor Sullivan

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ách C ++ của bạn sẽ không hoạt động vì operator <<trả về std::ostream&thay vì a stringstream&.
Konrad Rudolph

Có vẻ như các chuỗi của tôi hơi rỉ sét, tôi thích các cách của ol 'C. Đã sửa bây giờ (tôi hy vọng).
Adam Rosenfield

Mã C của bạn đã ném tôi lúc đầu. Tôi vẫn ủng hộ bạn vì đã đưa ra giải pháp thay thế chính xác.
Bill Lizard

2
upvote cho bao gồm cả cách C. có vẻ như rất sạch sẽ với tôi
Nealon

11
Nâng cấp cho cách C ++ 11. Tôi chưa quen với C ++ và không nhận ra rằng có một to_stringchức năng. Tôi đang sử dụng Microsoft Visual C ++ 2013.
Trevor Sullivan

123

Cách C ++ 11 tiêu chuẩn (nếu bạn không quan tâm đến định dạng đầu ra):

#include <string>

auto str = std::to_string(42.5); 

to_stringlà một chức năng thư viện mới được giới thiệu trong N1804 (r0), N1982 (r1) và N2408 (r2) " Truy cập số đơn giản ". Ngoài ra còn có stodchức năng thực hiện các hoạt động ngược lại.

Nếu bạn muốn có một định dạng đầu ra khác hơn "%f", hãy sử dụng snprintfhoặc ostringstreamcác phương thức như được minh họa trong các câu trả lời khác.


3
oh vâng, em yêu to_opes và stod đều hoạt động trong Visual Studio 11.
BSalita

Ôi trời ơi ... to_opes dường như không hoạt động trong VisualStudio 2010): Điều đó, hoặc tôi không biết mình đang làm gì (rất có thể)
Chessofnerd

1
Điều này nên cao hơn, vì nó hiện đại hơn!
gsamaras

1
Có cách nào để làm cho hàm này không thêm số thập phân hơn mức cần thiết không? Khi tôi chuyển đổi gấp đôi, 8.0nó cung cấp cho tôi chuỗi "8.000000", trong khi đó "8"sẽ hoàn toàn ổn.
HelloGoodbye

1
Điều này không hoạt động đối với số lượng nhỏ ... ví dụ: 1e-9sản xuất0.000000
user3728501

24

Nếu bạn sử dụng C ++, hãy tránh sprintf. Đó là un-C ++ y và có một số vấn đề. Chuỗi dòng là phương pháp được lựa chọn, tốt nhất là được gói gọn như trong Boost.LexicalCast có thể được thực hiện khá dễ dàng:

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

Sử dụng:

string s = to_string(42.5);

24

Bạn có thể sử dụng std :: to_opes trong C ++ 11

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

Số của tôi rất nhỏ, và std::to_string()chỉ trả về 0,000000 và không ở dạng khoa học.
erfan

11

sprintfkhông sao, nhưng trong C ++, cách chuyển đổi tốt hơn, an toàn hơn và cũng chậm hơn một chút với stringstream:

#include <sstream>
#include <string>

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

Bạn cũng có thể sử dụng Boost.LexicalCast :

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

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

Trong cả hai trường hợp, strnên được "453.23"sau đó. LexicalCast có một số lợi thế ở chỗ nó đảm bảo quá trình chuyển đổi hoàn tất. Nó sử dụng stringstreams trong nội bộ.


10

Tôi sẽ xem xét Bộ công cụ chuỗi C ++ Libary . Chỉ cần đăng một câu trả lời tương tự ở nơi khác. Tôi đã tìm thấy nó rất nhanh và đáng tin cậy.

#include <strtk.hpp>

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


6

Vấn đề với lexical_cast là không có khả năng xác định độ chính xác. Thông thường nếu bạn đang chuyển đổi gấp đôi thành một chuỗi, đó là vì bạn muốn in nó ra. Nếu độ chính xác quá nhiều hoặc quá ít, nó sẽ ảnh hưởng đến đầu ra của bạn.



4

Heh, tôi chỉ viết cái này (không liên quan đến câu hỏi này):

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

/* rest of the code */

2

Bạn có thể muốn đọc bài viết trước của tôi trên SO. (Phiên bản macro'ed với đối tượng tạo dòng tạm thời.)

Đối với bản ghi: Trong mã của riêng tôi, tôi ủng hộ snprintf (). Với một mảng char trên ngăn xếp cục bộ, nó không hiệu quả. (Chà, có lẽ nếu bạn vượt quá kích thước mảng và lặp đi lặp lại để làm điều đó hai lần ...)

(Tôi cũng đã gói nó thông qua vsnprintf (). Nhưng điều đó khiến tôi phải kiểm tra một số loại. Yelp nếu bạn muốn mã ...)


2

Hãy xem sprintf()và gia đình.


2
Tôi đã đề cập đến printf bởi vì googling đã đưa ra một loạt các bài báo nói để chuyển đổi từ một chuỗi thành một chuỗi bạn sử dụng printf. Họ đưa ra giả định rằng điều duy nhất bạn có thể làm là in, trong trường hợp của tôi là sai.
Bill Lizard

tại sao bạn bỏ phiếu -1? Tôi nghĩ chạy nước rút là tốt. @BilltheLizard, chạy nước rút in một cái gì đó lên màn hình char * không. Có người trả lời phương pháp c vẫn được nhiều phiếu.
Worldterminator

2

Normaly cho các hoạt động này, bạn phải sử dụng các hàm ecvt, fcvt hoặc 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   

Là một chức năng:

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

0

Bạn có thể thử một phong cách nhỏ gọn hơn:

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

Sử dụng to_string().
thí dụ :

#include <iostream>   
#include <string>  

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

  return 0;
}

tự chạy: http://ideone.com/7ejfaU
Đây cũng có sẵn:

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

Bạn có thể chuyển đổi mọi thứ thành bất cứ thứ gì bằng chức năng này:

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

sử dụng :

std::string str = to(2.5);
double d = to<double>("2.5");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.