làm thế nào để chuyển đổi từ int sang char *?


97

Cách duy nhất tôi biết là:

#include <sstream>
#include <string.h>
using namespace std;

int main() {
  int number=33;
  stringstream strs;
  strs << number;
  string temp_str = strs.str();
  char* char_type = (char*) temp_str.c_str();
}

Nhưng có phương pháp nào ít gõ hơn không?


8
tại sao bạn muốn một chuỗi C thay vì một chuỗi C ++?
KillianDS

1
sử dụng sprintf
Kasma

Câu trả lời:


127
  • Trong C ++ 17, sử dụng std::to_charsnhư:

    std::array<char, 10> str;
    std::to_chars(str.data(), str.data() + str.size(), 42);
  • Trong C ++ 11, sử dụng std::to_stringnhư:

    std::string s = std::to_string(number);
    char const *pchar = s.c_str();  //use char const* as target type
  • Và trong C ++ 03, những gì bạn đang làm rất ổn, ngoại trừ việc sử dụng constnhư:

    char const* pchar = temp_str.c_str(); //dont use cast

1
Phần đầu tiên không thực sự trả lời câu hỏi (mặc dù nó là thông tin hữu ích tốt như tôi đã không nhận thức được rằng chức năng)
jcoder

1
Tốt hơn :) Thêm vào đó, tôi nên đọc thêm về c ++ 11 một lần nữa. Tôi biết về các tính năng lớn nhưng điều này khiến tôi nhận ra có lẽ còn nhiều tính năng nhỏ mà tôi đã bỏ lỡ.
jcoder

1
@Adambean: Tại sao nó "không nên liên quan đến std :: string"? . Người ta nên sử dụng std::stringtheo mặc định, thay vì char*.
Nawaz

1
std :: string không phải lúc nào cũng có sẵn, đặc biệt đối với các dự án cũ hơn. Nhiều trò chơi C ++ cũng vẫn tránh xa std :: string. Đi từ int sang std :: string thành char * không giống với int sang char *.
Adambean

1
@Adambean: Nếu đó là C ++, thì tôi sẽ giả sử std::stringlà có sẵn theo mặc định, trừ khi nó được chỉ định rõ ràng trong chính câu hỏi. Có ý nghĩa? Ngoài ra, vì bản thân câu hỏi sử dụng std::string(và std::stringstream), nên bạn không có nhiều lý do để không đồng ý với nó.
Nawaz

11

Tôi nghĩ bạn có thể sử dụng sprintf:

int number = 33;
char* numberstring[(((sizeof number) * CHAR_BIT) + 2)/3 + 2];
sprintf(numberstring, "%d", number);

1
bạn nên thay đổi char * để char, ngay bây giờ numberstring là một mảng của con trỏ
josefx

1
Ngoài ra, bạn cần 12 ký tự để chuyển đổi một số nguyên 32 bit thành một biểu diễn cơ số 10 được kết thúc bằng nul. 10 là không đủ cho -2147483647.
Steve Jessop

11
Làm thế nào về một số giải thích? (((sizeof number) * CHAR_BIT) + 2)/3 + 2trông giống như thầy phù thủy ...
Mike S

7

Bạn có thể sử dụng boost

#include <boost/lexical_cast.hpp>
string s = boost::lexical_cast<string>( number );

5

Giải pháp kiểu C có thể được sử dụng itoa, nhưng cách tốt hơn là in số này thành chuỗi bằng cách sử dụng sprintf/snprintf . Kiểm tra câu hỏi này: Làm thế nào để chuyển đổi một số nguyên thành một chuỗi một cách di động?

Lưu ý rằng itoahàm không được định nghĩa trong ANSI-C và không phải là một phần của C ++, nhưng được hỗ trợ bởi một số trình biên dịch. Đó là một chức năng không chuẩn, do đó bạn nên tránh sử dụng nó. Kiểm tra câu hỏi này quá: Thay thế cho itoa () để chuyển đổi số nguyên thành chuỗi C ++?

Cũng lưu ý rằng viết mã kiểu C trong khi lập trình bằng C ++ được coi là hành vi xấu và đôi khi được gọi là "phong cách ghê rợn". Bạn có thực sự muốn chuyển nó thành char*chuỗi kiểu C không? :)


5

Tôi sẽ không đánh máy hằng số ở dòng cuối cùng vì nó có lý do. Nếu bạn không thể sống với const char * thì tốt hơn bạn nên sao chép mảng char như:

char* char_type = new char[temp_str.length()];
strcpy(char_type, temp_str.c_str());

ý bạn const char* char_type = temp_str.c_str();là tốt hơn?
rsk82

1
Đúng. c_str cung cấp cho bạn một con trỏ đến bộ đệm bên trong của đối tượng chuỗi. Nếu bạn loại bỏ const, bạn hoặc một lập trình viên khác có thể nghĩ rằng có thể thay đổi bộ đệm thông qua biến không phải const. Nhưng nó không phải như vậy. Đối tượng chuỗi ban đầu không biết gì về những thay đổi này. Mặt khác chuỗi vẫn sở hữu bộ đệm. Nếu đối tượng chuỗi đi ra ngoài phạm vi, bộ nhớ đằng sau con trỏ sẽ bị xóa bởi bộ hủy đối tượng chuỗi để lại cho bạn một con trỏ lơ lửng. Thao tác sao chép loại bỏ cả hai vấn đề.
user331471

1
Ngoài ra std::vector<char> temp_vec(temp_str.begin(), temp_str.end()); temp_vec.push_back(0); char *char_type = &vec[0];,. Điều này cung cấp cho bạn bộ nhớ có thể thay đổi, mặc dù tất nhiên bạn vẫn cần giữ cho vector tồn tại miễn là bạn muốn sử dụng con trỏ.
Steve Jessop

1
Hoặc chỉ cần sử dụng stringvà không bận tâm với cũ, đơn giản, ngu ngốc char *từ cũ, đơn giản C. <bit của ngọn lửa dự định>
Griwes

@Griwes: câu hỏi là làm thế nào để truy cập char*, không phải "có điểm nào gọi từ C ++ vào các thư viện hiện có được viết bằng C không, hay tôi nên triển khai lại chúng trong C ++?" ;-p
Steve Jessop

2

Được rồi .. trước hết tôi cần thứ gì đó đã làm được những gì câu hỏi này đang hỏi, nhưng tôi cần nó NHANH CHÓNG! Thật không may là cách "tốt hơn" là gần 600 dòng mã !!! Xin lỗi vì cái tên của nó không liên quan gì đến những gì nó đang làm. Tên riêng là Integer64ToCharArray (giá trị int64_t);

https://github.com/JeremyDX/All-Language-Testing-Code/blob/master/C%2B%2B%20Examples/IntegerToCharArrayTesting.cpp

Hãy thử xóa mã đó mà không cản trở hiệu suất.

Đầu vào: Bất kỳ giá trị 64 bit nào có dấu từ phạm vi tối thiểu đến tối đa.

Thí dụ:

std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MAX) << '\n';
std::cout << "Test: " << AddDynamicallyToBuffer(LLONG_MIN) << '\n';

Đầu ra:

Test: 9223372036854775807
Test: -9223372036854775808

Kiểm tra tốc độ gốc: ( Integer64ToCharArray (); )

Trường hợp tốt nhất giá trị 1 chữ số.

Số vòng lặp: 100.000.000, Thời gian tiêu tốn: 1.381 (Milli), Thời gian mỗi vòng 13 (Nano)

Trường hợp tồi tệ hơn Giá trị 20 chữ số.

Số vòng lặp: 100.000.000, Thời gian sử dụng: 22.656 (Milli), Thời gian mỗi vòng 226 (Nano

Kiểm tra tốc độ thiết kế mới: ( AddDynamentlyToBuffer (); )

Trường hợp tốt nhất giá trị 1 chữ số.

Số vòng lặp: 100.000.000, Thời gian tiêu tốn: 427 (Milli), Thời gian mỗi vòng 4 (Nano)

Trường hợp xấu nhất 32 bit - Giá trị 11 chữ số.

Số vòng lặp: 100.000.000, Thời gian tiêu tốn: 1.991 (Milli), Thời gian mỗi vòng 19 (Nano)

Âm 1 nghìn tỷ Trường hợp xấu nhất - Giá trị 14 chữ số.

Số vòng lặp: 100.000.000, Thời gian tiêu tốn: 5.681 (Milli), Thời gian mỗi vòng 56 (Nano)

Trường hợp xấu hơn 64 bit - Giá trị 20 chữ số.

Số vòng lặp: 100.000.000, Thời gian tiêu tốn: 13.148 (Milli), Thời gian mỗi vòng 131 (Nano)

Làm thế nào nó hoạt động!

Chúng tôi thực hiện kỹ thuật Chia và Chinh phục và khi chúng tôi đã đạt độ dài tối đa của chuỗi, chúng tôi chỉ cần đặt từng giá trị ký tự riêng lẻ. Như được hiển thị trong các bài kiểm tra tốc độ ở trên, độ dài lớn hơn sẽ bị phạt hiệu suất lớn, nhưng nó vẫn nhanh hơn nhiều so với phương pháp lặp ban đầu và không có mã nào thực sự thay đổi giữa hai phương pháp khác thì vòng lặp không còn được sử dụng nữa.

Trong cách sử dụng của tôi, do đó, tôi trả về giá trị thay thế và tôi không chỉnh sửa vùng đệm các mảng char thay vì tôi bắt đầu cập nhật dữ liệu đỉnh và hàm có một tham số bổ sung cho offset nên nó không được khởi tạo thành -1.




0

Bạn cũng có thể sử dụng đúc.

thí dụ:

string s;
int value = 3;
s.push_back((char)('0' + value));

1
Điều gì xảy ra nếu giá trị là âm hoặc không phải là một chữ số?
Ziya ERKOC
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.