Làm thế nào để nối char vào chuỗi std ::?


175

Lỗi sau đây với lỗi prog.cpp:5:13: error: invalid conversion from ‘char’ to ‘const char*’

int main()
{
  char d = 'd';
  std::string y("Hello worl");
  y.append(d); // Line 5 - this fails
  std::cout << y;
  return 0;
}

Tôi cũng đã thử, sau đây, nó biên dịch nhưng hoạt động ngẫu nhiên trong thời gian chạy:

int main()
{
  char d[1] = { 'd' };
  std::string y("Hello worl");
  y.append(d);
  std::cout << y;
  return 0;
}

Xin lỗi vì câu hỏi ngớ ngẩn này, nhưng tôi đã tìm kiếm trên google, những gì tôi có thể thấy chỉ là "char mảng to char ptr", "char ptr to char mảng", v.v.


một lỗi biên dịch có..Tôi quên lỗi là gì, nhưng nó hợp lý.
chết đuối

3
Bạn có câu trả lời tốt hơn bên dưới, nhưng bạn có thể làm cho bạn ví dụ thứ hai hoạt động như char d [2] = {'d', 0}; hoặc chỉ char d [2] = "d"; Về cơ bản, bạn cần số 0 để chấm dứt chuỗi kiểu c mà bạn chuyển sang nối thêm
sbk

Tài liệu tốt ở đây: sgi.com/tech/stl/basic_opes.html
Martin York

Câu trả lời:


224
y += d;

Tôi sẽ sử dụng +=toán tử thay vì các chức năng được đặt tên.


2
Tại sao bạn xem xét + = tốt hơn Push_back? Nó chỉ là ít gõ hoặc bạn có một lý do khác?
Glen

4
Nó ít gõ hơn. Trong gcc, basic_string::operator+=chỉ là một cuộc gọi trong push_back.
phù nề

2
Đó là IMO tự nhiên hơn cho chuỗi. Push_back là hàm chứa và một chuỗi là một chuỗi chuyên biệt trong STL :)
AraK

6
Chúng ta hãy chuyển câu hỏi đó: Tại sao bạn lại xem Push_back tốt hơn + =? Theo tôi, + = là rõ ràng và súc tích.
Jesper

34
Bạn muốn cẩn thận với điều này bởi vì nếu bạn có thói quen, điều này sẽ biên dịch tốt nếu ychar*thay vì std::string. Nó sẽ thêm các dký tự vào con trỏ y.
Zan Lynx


19

Để thêm char vào std :: string var bằng phương thức chắp thêm, bạn cần sử dụng quá tải này:

std::string::append(size_type _Count, char _Ch)

Chỉnh sửa: Bạn nói đúng Tôi đã hiểu nhầm tham số size_type, được hiển thị trong trợ giúp ngữ cảnh. Đây là số lượng ký tự để thêm. Vì vậy, cuộc gọi chính xác là

s.append(1, d);

không phải

s.append(sizeof(char), d);

Hoặc cách đơn giản nhất:

s += d;

Tôi nghĩ rằng việc sử dụng sizeof không đúng về mặt ngữ nghĩa ở đây (mặc dù nó có thể hoạt động vì sizeof (char) luôn là một). Phương thức chắp thêm tự nhiên hữu ích hơn nếu bạn muốn chắp thêm nhiều bản sao của cùng một nhân vật !!!!!!!!!!
ChúBens

1
Tại sao bạn sử dụng sizeof(char)thay vì 1? Bạn muốn nối chính xác một lần lặp lại d, vì vậy chỉ cần nói rằng. Sử dụng sizeofở đây là sai lệch vì nó gợi ý rằng người ta phải nói appendkích thước byte của loại dữ liệu được sử dụng (không phải là trường hợp).
Ferdinand Beyer

Như chú đã nói, phương pháp chắp thêm thực sự hữu ích hơn khi thêm cùng một ký tự nhiều lần.
Patrice Bernassola

10

Ngoài những cái khác được đề cập, một trong những hàm tạo chuỗi lấy một char và số lần lặp lại cho char đó. Vì vậy, bạn có thể sử dụng nó để nối một char duy nhất.

std::string s = "hell";
s += std::string(1, 'o');

7

Tôi kiểm tra một số đề xuất bằng cách chạy chúng vào một vòng lặp lớn. Tôi đã sử dụng microsoft visual studio 2015 làm trình biên dịch và bộ xử lý của tôi là i7, 8Hz, 2GHz.

    long start = clock();
    int a = 0;
    //100000000
    std::string ret;
    for (int i = 0; i < 60000000; i++)
    {
        ret.append(1, ' ');
        //ret += ' ';
        //ret.push_back(' ');
        //ret.insert(ret.end(), 1, ' ');
        //ret.resize(ret.size() + 1, ' ');
    }
    long stop = clock();
    long test = stop - start;
    return 0;

Theo thử nghiệm này, kết quả là:

     operation             time(ms)            note
------------------------------------------------------------------------
append                     66015
+=                         67328      1.02 time slower than 'append'
resize                     83867      1.27 time slower than 'append'
push_back & insert         90000      more than 1.36 time slower than 'append'

Phần kết luận

+= có vẻ dễ hiểu hơn, nhưng nếu bạn bận tâm về tốc độ, hãy sử dụng nối thêm


Để câu trả lời như vậy có ý nghĩa, ít nhất bạn nên nói trình biên dịch nào bạn đang sử dụng, bởi vì những thứ như vậy có thể thay đổi RẤT NHIỀU. Kể về bộ xử lý của bạn cũng có thể rất tuyệt, để có được ước tính sơ bộ về tác động thực tế mà điều này có thể gây ra.
akaltar

Tôi đã sử dụng visual studio 2015. Tôi sẽ tìm gcc để thực hiện một số thử nghiệm khác. Bộ xử lý của tôi là i7, 8 trái tim, 2.20 Ghz .... Nhưng dù là bộ xử lý của tôi thì nó cũng không ảnh hưởng gì đến việc thực hiện chuỗi std :: ... ngoại trừ nếu một số phương pháp này là đa luồng và một số bà mẹ thì không.
Hugo Zevetel

Đôi khi nó có tác động, đặc biệt nếu bạn đang hiển thị thời gian tính bằng mili giây. Thay vào đó, bạn có thể hiển thị theo tỷ lệ phần trăm so với phương pháp nhanh nhất (Vì vậy, tốc độ bộ xử lý thực tế là không liên quan) Cũng di chuyển dữ liệu đó từ nhận xét sang câu trả lời của bạn, đây chỉ là nghi thức chung của StackExchange. Nếu không thì trả lời tốt đẹp.
akaltar


2

vấn đề với:

std::string y("Hello worl");
y.push_back('d')
std::cout << y;

là bạn phải có 'd' trái ngược với việc sử dụng tên của char, như char d = 'd'; Hoặc là tôi sai?


Tôi chỉ thử nó và nó hoạt động tốt. Tôi có char c = 'd'và tôi có thể làm y.push_back(c)mà không có vấn đề. Vì vậy, không có vấn đề gì với std::string::push_back()(ngoại trừ việc nó dài hơn +=).
Franklin Yu

1
int main()
{
  char d = 'd';
  std::string y("Hello worl");

  y += d;
  y.push_back(d);
  y.append(1, d); //appending the character 1 time
  y.insert(y.end(), 1, d); //appending the character 1 time
  y.resize(y.size()+1, d); //appending the character 1 time
  y += std::string(1, d); //appending the character 1 time
}

Lưu ý rằng trong tất cả các ví dụ này, bạn có thể đã sử dụng một ký tự theo nghĩa đen trực tiếp : y += 'd';.

Ví dụ thứ hai của bạn gần như sẽ có hiệu quả, vì những lý do không liên quan. char d[1] = { 'd'};không hoạt động, nhưng char d[2] = { 'd'};(lưu ý mảng có kích thước hai) sẽ được làm việc gần giống như const char* d = "d";, và một chuỗi ký tự có thể được thêm vào : y.append(d);.


1

Hãy thử sử dụng con trỏ d là y.append (* d)


Điều đó nguy hiểm vì một đơn charlà không có chuỗi và không có kết thúc null. Làm điều này gây ra hành vi không xác định.
Simon Kraemer

Điều này chỉ sai. *dcó nghĩa là con trỏ khử tham chiếu dlà lỗi cú pháp vì dkhông phải là con trỏ.
Franklin Yu

0
str.append(10u,'d'); //appends character d 10 times

Lưu ý rằng tôi đã viết 10u chứ không phải 10 cho số lần tôi muốn thêm nhân vật; thay 10 bằng bất cứ số nào.


0

Tôi tìm thấy một cách đơn giản ... Tôi cần phải charxử lý một chuỗi đang được xây dựng khi đang bay. Tôi cần một char list;vì tôi đã cho người dùng lựa chọn và sử dụng lựa chọn đó trong một switch()tuyên bố.

Tôi chỉ cần thêm một std::string Slist;chuỗi khác và đặt chuỗi mới bằng với ký tự, "danh sách" - a, b, c hoặc bất cứ điều gì người dùng cuối chọn như thế này:

char list;
std::string cmd, state[], Slist;
Slist = list; //set this string to the chosen char;
cmd = Slist + state[x] + "whatever";
system(cmd.c_str());

Sự phức tạp có thể mát mẻ nhưng sự đơn giản là mát mẻ hơn. IMHO


0

Ngoài ra thêm tùy chọn chèn, như chưa được đề cập.

std::string str("Hello World");
char ch;

str.push_back(ch);  //ch is the character to be added
OR
str.append(sizeof(ch),ch);
OR
str.insert(str.length(),sizeof(ch),ch) //not mentioned above

-1

Nếu bạn đang sử dụng Push_back, không có lệnh gọi cho hàm tạo chuỗi. Nếu không, nó sẽ tạo một đối tượng chuỗi thông qua việc truyền, sau đó nó sẽ thêm ký tự trong chuỗi này vào chuỗi khác. Quá nhiều rắc rối cho một nhân vật nhỏ bé;)


1
toán tử + = (char c); bị quá tải cho chuỗi. Trên thực tế, hàm tạo chuỗi không chấp nhận một ký tự, xem câu trả lời của Brian;)
AraK
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.