Làm thế nào để in ra nội dung của một vector?


281

Tôi muốn in ra nội dung của một vectơ trong C ++, đây là những gì tôi có:

#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
#include <cstdio>
using namespace std;

int main()
{
    ifstream file("maze.txt");
    if (file) {
        vector<char> vec(istreambuf_iterator<char>(file), (istreambuf_iterator<char>()));
        vector<char> path;
        int x = 17;
        char entrance = vec.at(16);
        char firstsquare = vec.at(x);
        if (entrance == 'S') { 
            path.push_back(entrance); 
        }
        for (x = 17; isalpha(firstsquare); x++) {
            path.push_back(firstsquare);
        }
        for (int i = 0; i < path.size(); i++) {
            cout << path[i] << " ";
        }
        cout << endl;
        return 0;
    }
}

Làm cách nào để in nội dung của vectơ lên ​​màn hình?


1
Tại sao nó không làm việc"?
Mặc định

Câu trả lời:


392

Hoàn toàn để trả lời câu hỏi của bạn, bạn có thể sử dụng một trình vòng lặp:

std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

Nếu bạn muốn sửa đổi nội dung của vectơ trong vòng lặp for, thì hãy sử dụng iteratorchứ không phải const_iterator.

Nhưng có rất nhiều điều có thể nói về điều này. Nếu bạn chỉ muốn một câu trả lời bạn có thể sử dụng, thì bạn có thể dừng ở đây; mặt khác, đọc tiếp

tự động (C ++ 11) / typedef

Đây không phải là một giải pháp khác, mà là một bổ sung cho iteratorgiải pháp trên . Nếu bạn đang sử dụng tiêu chuẩn C ++ 11 (hoặc mới hơn), thì bạn có thể sử dụng autotừ khóa để giúp dễ đọc:

for (auto i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

Nhưng loại isẽ không phải là const (tức là trình biên dịch sẽ sử dụng std::vector<char>::iteratorlàm kiểu i).

Trong trường hợp này, bạn cũng có thể chỉ sử dụng một typedef(không giới hạn ở C ++ 11 và rất hữu ích để sử dụng):

typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
    std::cout << *i << ' ';

quầy tính tiền

Tất nhiên, bạn có thể sử dụng loại số nguyên để ghi lại vị trí của mình trong forvòng lặp:

for(int i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

Nếu bạn định làm điều này, tốt hơn là sử dụng các loại thành viên của bộ chứa, nếu chúng có sẵn và phù hợp. std::vectorcó một loại thành viên được gọi size_typecho công việc này: đó là loại được trả về bởi sizephương thức.

// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
  std::cout << path[i] << ' ';

Tại sao không chỉ sử dụng điều này trên các iteratorgiải pháp? Đối với các trường hợp đơn giản, bạn cũng có thể, nhưng vấn đề là iteratorlớp là một đối tượng được thiết kế để thực hiện công việc này cho các đối tượng phức tạp hơn, nơi giải pháp này sẽ không lý tưởng.

dựa trên phạm vi cho vòng lặp (C ++ 11)

Xem giải pháp của Jefffrey . Trong C ++ 11 (và phiên bản mới hơn), bạn có thể sử dụng forvòng lặp dựa trên phạm vi mới , trông giống như sau:

for (auto i: path)
  std::cout << i << ' ';

pathlà một vectơ của các mục (rõ ràng std::vector<char>), đối tượngi là loại của mục của vectơ (tức là, rõ ràng, nó là loại char). Đối tượng icó một giá trị là một bản sao của mục thực tế trong pathđối tượng. Do đó, tất cả các thay đổi itrong vòng lặp không được bảo tồn trong pathchính nó. Ngoài ra, nếu bạn muốn thực thi thực tế là bạn không muốn để có thể thay đổi giá trị sao chép của itrong vòng lặp, bạn có thể buộc các loại iconst charnhư thế này:

for (const auto i: path)
  std::cout << i << ' ';

Nếu bạn muốn sửa đổi các mục trong path, bạn có thể sử dụng một tài liệu tham khảo:

for (auto& i: path)
  std::cout << i << ' ';

và ngay cả khi bạn không muốn sửa đổi path, nếu việc sao chép các đối tượng đắt tiền, bạn nên sử dụng tham chiếu const thay vì sao chép theo giá trị:

for (const auto& i: path)
  std::cout << i << ' ';

std :: bản sao

Xem câu trả lời của Joshua . Bạn có thể sử dụng thuật toán STL std::copyđể sao chép nội dung vectơ vào luồng đầu ra. Đây là một giải pháp tao nhã nếu bạn cảm thấy thoải mái với nó (và bên cạnh đó, nó rất hữu ích, không chỉ trong trường hợp in nội dung của một vectơ).

std :: for_each

Xem giải pháp của Max . Sử dụngstd::for_each là quá mức cần thiết cho kịch bản đơn giản này, nhưng nó là một giải pháp rất hữu ích nếu bạn muốn làm nhiều hơn là chỉ in ra màn hình: sử dụng std::for_eachcho phép bạn thực hiện bất kỳ thao tác (hợp lý) nào trên nội dung vectơ.

quá tải Ostream :: toán tử <<

Xem câu trả lời của Chris , đây là phần bổ sung cho các câu trả lời khác vì bạn vẫn sẽ cần phải thực hiện một trong những giải pháp ở trên trong tình trạng quá tải. Trong ví dụ của mình, anh ta đã sử dụng một bộ đếm trong một forvòng lặp. Ví dụ, đây là cách bạn có thể nhanh chóng sử dụng giải pháp của Joshua :

template <typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
  if ( !v.empty() ) {
    out << '[';
    std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
    out << "\b\b]";
  }
  return out;
}

Việc sử dụng bất kỳ giải pháp nào khác nên đơn giản.

phần kết luận

Bất kỳ giải pháp được trình bày ở đây sẽ làm việc. Tùy thuộc vào bạn và mã mà cái nào là "tốt nhất". Bất cứ điều gì chi tiết hơn điều này có lẽ là tốt nhất để lại cho một câu hỏi khác trong đó những ưu / nhược điểm có thể được đánh giá đúng; nhưng như mọi khi, sở thích của người dùng sẽ luôn đóng một phần: không có giải pháp nào được trình bày là sai, nhưng một số giải pháp sẽ đẹp hơn đối với mỗi lập trình viên riêng lẻ.

phụ lục

Đây là một giải pháp mở rộng của một giải pháp trước đó tôi đã đăng. Vì bài đăng đó tiếp tục được chú ý, tôi quyết định mở rộng về nó và tham khảo các giải pháp tuyệt vời khác đã được đăng ở đây. Bài viết gốc của tôi có một nhận xét đề cập rằng nếu bạn đang có ý định sửa đổi vectơ của mình trong một forvòng lặp thì có hai phương thức được cung cấp std::vectorđể truy cập các phần tử: std::vector::operator[]không thực hiện kiểm tra giới hạn và std::vector::atthực hiện kiểm tra giới hạn. Nói cách khác, atsẽ ném nếu bạn cố gắng truy cập một phần tử bên ngoài vectơ và operator[]sẽ không. Tôi chỉ thêm bình luận này, ban đầu, vì mục đích đề cập đến một cái gì đó có thể hữu ích để biết nếu có ai đã không làm. Và tôi thấy không có sự khác biệt bây giờ. Do đó phụ lục này.


Nếu bạn đang lặp từ 0xuyên suốt vector::size()và vectơ không được sửa đổi trong vòng lặp thì không cần sử dụng at()và phải chịu các giới hạn kiểm tra thêm. Điều đó nói rằng, tôi sẽ đi với một iterator như bạn đề nghị.
Ed S.

1
@Ed: yeah, không có điểm nào trong việc sử dụng atnếu không có gì trong vòng lặp sửa đổi vectơ, nhưng tôi nghĩ tôi chỉ đề cập đến nó trong trường hợp vectơ được sửa đổi trong vòng lặp (không được khuyến khích như vậy) và bởi vì nó không bao giờ có được đề cập đến và nó có thể hữu ích để, ít nhất, biết về nó.
Zorawar

Vòng lặp dựa trên phạm vi có thể được viết lại để sử dụng các tham chiếu, điều này có thể quan trọng trong trường hợp các đối tượng phụ lớn, như sau:for (auto const &i: path) std::cout << i << ' ';
underscore_d

@underscore_d: cảm ơn. Tôi đã dọn sạch phần đó và tôi hy vọng nó hoàn thiện hơn và rõ ràng hơn một chút.
Zorawar

"Toán tử quá tải <<" không phải là một giải pháp tốt; ít nhất một toán hạng của toán tử quá tải phải là một lớp được xác định bởi chương trình của bạn, vì tra cứu phụ thuộc vào đối số
MM

218

Một cách dễ dàng hơn nhiều để làm điều này là với thuật toán sao chép tiêu chuẩn :

#include <iostream>
#include <algorithm> // for copy
#include <iterator> // for ostream_iterator
#include <vector>

int main() {
    /* Set up vector to hold chars a-z */
    std::vector<char> path;
    for (int ch = 'a'; ch <= 'z'; ++ch)
        path.push_back(ch);

    /* Print path vector to console */
    std::copy(path.begin(), path.end(), std::ostream_iterator<char>(std::cout, " "));

    return 0;
}

Ostream_iterator là cái được gọi là bộ điều hợp lặp . Nó được templatized trên các loại để in ra luồng (trong trường hợp này, char). cout(còn gọi là đầu ra giao diện điều khiển) là luồng chúng tôi muốn ghi và ký tự khoảng trắng (" " ) là ta muốn in giữa mỗi phần tử được lưu trữ trong vectơ.

Thuật toán tiêu chuẩn này rất mạnh và nhiều người khác cũng vậy. Sức mạnh và tính linh hoạt mà thư viện tiêu chuẩn mang lại cho bạn là những gì làm cho nó trở nên tuyệt vời. Chỉ cần tưởng tượng: bạn có thể in một vectơ lên ​​bàn điều khiển chỉ với một dòng mã. Bạn không phải đối phó với các trường hợp đặc biệt với ký tự phân cách. Bạn không cần phải lo lắng về vòng lặp for. Thư viện tiêu chuẩn làm tất cả cho bạn.


3
Điều gì xảy ra nếu vector của tôi thuộc loại vector<pair<int, struct node>>. Làm thế nào để tôi sử dụng phương pháp trên để in vector này?
mtk

6
Chuỗi phân cách được viết sau mỗi phần tử, không phải giữa, tức là, sau phần cuối cùng. Điều đó có thể yêu cầu xử lý các trường hợp đặc biệt nếu bạn chỉ muốn nó ở giữa, tức là, như một dấu phân cách.
Quigi

2
@mtk bạn có thể khai báo một operator<<hàm cho cặp cụ thể của bạn <>.
Đánh giày

Đã thêm một câu trả lời cho thấy một cách tiếp cận tương tự nhưng đưa vào nhận xét @Quigi: s ở trên, liên quan đến dấu phân cách thêm.
dfri

@ShoeLace Có cách nào khác không?
thegreatcoder

69

Trong C ++ 11 bây giờ bạn có thể sử dụng vòng lặp dựa trên phạm vi :

for (auto const& c : path)
    std::cout << c << ' ';

Điều này chỉ hoạt động tuyệt vời nếu kích thước của vectơ không thay đổi trong phần thân của phạm vi vòng lặp.
Brian

8
@BrianP. Vâng In các phần tử của một container không sửa đổi phạm vi của container.
Giày

Điều gì thích hợp hơn ở đây - c là bản sao giá trị hoặc tham chiếu const để tránh sao chép phần tử?
kleinfreund 17/05/2015

@kleinfreund Nó phụ thuộc vào nội dung của vectơ. Ví dụ, đối với một vectơ chars, rất có thể việc chuyển qua tham chiếu không đổi thực sự tốn kém hơn so với giá trị. Nhưng ở đây chúng ta đang nói về tối ưu hóa siêu vi.
Giày

43

Tôi nghĩ cách tốt nhất để làm điều này là chỉ quá tải operator<<bằng cách thêm chức năng này vào chương trình của bạn:

#include <vector>
using std::vector;
#include <iostream>
using std::ostream;

template<typename T>
ostream& operator<< (ostream& out, const vector<T>& v) {
    out << "{";
    size_t last = v.size() - 1;
    for(size_t i = 0; i < v.size(); ++i) {
        out << v[i];
        if (i != last) 
            out << ", ";
    }
    out << "}";
    return out;
}

Sau đó, bạn có thể sử dụng <<toán tử trên bất kỳ vectơ nào có thể, giả sử các phần tử của nó cũng đã ostream& operator<<xác định:

vector<string>  s = {"first", "second", "third"};
vector<bool>    b = {true, false, true, false, false};
vector<int>     i = {1, 2, 3, 4};
cout << s << endl;
cout << b << endl;
cout << i << endl;

Đầu ra:

{first, second, third}
{1, 0, 1, 0, 0}
{1, 2, 3, 4}

3
Lưu trữ v.size () - 1 dưới dạng int là khả năng mất độ chính xác. Tôi đã sửa lỗi này trong một chỉnh sửa được đánh giá ngang hàng được chấp nhận ( stackoverflow.com/revutions/23397700/5 ), nhưng sau đó nó đã được chỉnh sửa một lần nữa để khôi phục sự mất độ chính xác có thể. Tôi đoán nó không quan trọng lắm trong thực tế vì vectơ thường không lớn như vậy.
JDiMatteo

Không lưu trữ nó dưới dạng một biến làm giảm khả năng đọc mã, đây là một phần trong chỉnh sửa của bạn mà tôi không đồng ý. Tôi đã thay đổi loại lastthành size_t.
Chris Redford

size_t last = v.size() - 1;Có vẻ dư thừa, bạn có thể sử dụng if (i) out << ", ";điều kiện trước khi out << v[i]; liên kết
Vladimir Gamalyan

3
Toán tử này không được tìm thấy bởi ADL, vì nó không nằm trong không gian tên của bất kỳ đối số nào của nó. Vì vậy, nó sẽ bị ẩn bởi bất kỳ không gian tên nào khác operator<<. Ví dụ
MM

Nếu bạn sẽ làm điều này, tại sao phải kiểm tra if (i != last) mỗi lần trong vòng lặp? Thay vào đó, nếu container không trống thì (a) gửi phần tử đầu tiên và sau đó (b) gửi vòng lặp các phần tử còn lại , in dấu phân cách trước (làm tiền tố). Không có kiểm tra vòng lặp bên trong (ngoài chính điều kiện vòng lặp) là bắt buộc. Chỉ có một thử nghiệm ngoài vòng lặp là bắt buộc.
WhozCraig

22

Làm thế nào về for_eachbiểu thức + lambda :

#include <vector>
#include <algorithm>
...
std::vector<char> vec;
...
std::for_each(
              vec.cbegin(),
              vec.cend(),
              [] (const char c) {std::cout << c << " ";} 
              );
...

Tất nhiên, một phạm vi dựa trên là giải pháp thanh lịch nhất cho nhiệm vụ cụ thể này, nhưng điều này cũng mang lại nhiều khả năng khác.

Giải trình

Các for_eachthuật toán có một phạm vi đầu vào và một đối tượng có thể được gọi , kêu gọi đối tượng này trên mọi phần tử của dãy núi này. Một phạm vi đầu vào được xác định bởi hai vòng lặp . Một đối tượng có thể gọi được có thể là một hàm, một con trỏ tới hàm, một đối tượng của một lớp quá tải () operatorhoặc như trong trường hợp này, một biểu thức lambda . Tham số cho biểu thức này khớp với loại của các phần tử từ vectơ.

Vẻ đẹp của việc triển khai này là sức mạnh bạn có được từ các biểu thức lambda - bạn có thể sử dụng phương pháp này cho nhiều thứ hơn là chỉ in vector.


10

Chỉ cần sao chép container vào giao diện điều khiển.

std::vector<int> v{1,2,3,4};
std::copy(v.begin(),v.end(),std::ostream_iterator<int>(std::cout, " " ));

Nên đầu ra:

1 2 3 4

8

Vấn đề có lẽ là trong vòng lặp trước : (x = 17; isalpha(firstsquare); x++). Vòng lặp này sẽ không chạy hoàn toàn (nếu firstsquarekhông phải là alpha) hoặc sẽ chạy mãi mãi (nếu đó là alpha). Lý do là firstsquarekhông thay đổi khi xtăng.


7

Trong C ++ 11, một vòng lặp dựa trên phạm vi có thể là một giải pháp tốt:

vector<char> items = {'a','b','c'};
for (char n : items)
    cout << n << ' ';

Đầu ra:

a b c 

6

Sử dụng std::copynhưng không có dấu phân cách phụ

Một cách tiếp cận thay thế / sửa đổi bằng cách sử dụng std::copy(như được sử dụng ban đầu trong câu trả lời @JoshuaKravtiz ) nhưng không bao gồm một dấu phân cách bổ sung sau phần tử cuối cùng:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

template <typename T>
void print_contents(const std::vector<T>& v, const char * const separator = " ")
{
    if(!v.empty())
    {
        std::copy(v.begin(),
                  --v.end(),
                  std::ostream_iterator<T>(std::cout, separator));
        std::cout << v.back() << "\n";
    }
}

// example usage
int main() {
    std::vector<int> v{1, 2, 3, 4};
    print_contents(v);      // '1 2 3 4'
    print_contents(v, ":"); // '1:2:3:4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // '1'
    return 0;
}

Sử dụng ví dụ được áp dụng cho vùng chứa loại POD tùy chỉnh:

// includes and 'print_contents(...)' as above ...

class Foo
{
    int i;
    friend std::ostream& operator<<(std::ostream& out, const Foo& obj);
public:
    Foo(const int i) : i(i) {}
};

std::ostream& operator<<(std::ostream& out, const Foo& obj)
{
    return out << "foo_" << obj.i; 
}

int main() {
    std::vector<Foo> v{1, 2, 3, 4};
    print_contents(v);      // 'foo_1 foo_2 foo_3 foo_4'
    print_contents(v, ":"); // 'foo_1:foo_2:foo_3:foo_4'
    v = {};
    print_contents(v);      // ... no std::cout
    v = {1};
    print_contents(v);      // 'foo_1'
    return 0;
}

3

Tôi thấy hai vấn đề. Như đã chỉ ra trong for (x = 17; isalpha(firstsquare); x++)đó có một vòng lặp vô hạn hoặc hoàn toàn không bao giờ được thực hiện, và trong trường if (entrance == 'S')hợp ký tự đầu vào khác với 'S' thì không có gì được đẩy vào vectơ đường dẫn, làm cho nó trống rỗng và do đó không in được gì trên màn hình. Bạn có thể kiểm tra kiểm tra sau path.empty()hoặc inpath.size() .

Dù bằng cách nào, sẽ tốt hơn nếu sử dụng một chuỗi thay vì một vectơ? Bạn cũng có thể truy cập nội dung chuỗi như một mảng, tìm kiếm các ký tự, trích xuất các chuỗi con và in chuỗi dễ dàng (không có vòng lặp).

Làm tất cả với các chuỗi có thể là cách để nó được viết theo cách ít phức tạp hơn và dễ dàng phát hiện ra vấn đề hơn.


3

toán tử quá tải <<:

template<typename OutStream, typename T>
OutStream& operator<< (OutStream& out, const vector<T>& v)
{
    for (auto const& tmp : v)
        out << tmp << " ";
    out << endl;
    return out;
}

Sử dụng:

vector <int> test {1,2,3};
wcout << test; // or any output stream

3

Câu trả lời này dựa trên câu trả lời từ Zorawar, nhưng tôi không thể để lại nhận xét ở đó.

Bạn có thể tạo phiên bản tự động (C ++ 11) / typedef const bằng cách sử dụng cbegin và cend thay thế

for (auto i = path.cbegin(); i != path.cend(); ++i)
    std::cout << *i << ' ';

1

Trong C ++ 11``

for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';

for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';

Câu trả lời này không cung cấp bất kỳ thông tin bổ sung nào so với các câu trả lời đã có.
Yashas

0
#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector <pair<string,int> > v;
    int n;
    cin>>n;
int i;
    for( i=0;i<n;i++)
    {
        int  end;
        string str;
        cin>>str;
        cin>>end;
        v.push_back(make_pair(str,end));
    }



for (int j=0;j<n;j++)
{
    cout<<v[j].first<< " "<<v[j].second<<endl;
}``
}

2
Chào! Chào mừng đến với stackoverflow. Sẽ thật tuyệt nếu bạn có thể kèm theo đoạn mã một số giải thích về những gì bạn đang làm và cách nó trả lời câu hỏi.
Slabgorb


0

Điều này làm việc cho tôi:

    for (auto& i : name)
    {
    int r = 0;
    for (int j = 0; j < name[r].size();j++) 
    {
    std::cout << i[j];
    }
    r++;
    std::cout << std::endl;
    }

0

Đối với những người quan tâm: Tôi đã viết một giải pháp tổng quát sử dụng tốt nhất cả hai thế giới, khái quát hơn cho bất kỳ loại phạm vi nào và đặt dấu ngoặc kép quanh các loại không số học (mong muốn cho các loại giống như chuỗi). Ngoài ra, cách tiếp cận này không nên có bất kỳ vấn đề ADL nào và cũng tránh được 'những điều bất ngờ' (vì nó được bổ sung rõ ràng trên cơ sở từng trường hợp cụ thể):

template <typename T>
inline constexpr bool is_string_type_v = std::is_convertible_v<const T&, std::string_view>;

template<class T>
struct range_out {
  range_out(T& range) : r_(range) {
  }
  T& r_;
  static_assert(!::is_string_type_v<T>, "strings and string-like types should use operator << directly");
};

template <typename T>
std::ostream& operator<< (std::ostream& out, range_out<T>& range) {
  constexpr bool is_string_like = is_string_type_v<T::value_type>;
  constexpr std::string_view sep{ is_string_like ? "', '" : ", " };

  if (!range.r_.empty()) {
    out << (is_string_like ? "['" : "[");
    out << *range.r_.begin();
    for (auto it = range.r_.begin() + 1; it != range.r_.end(); ++it) {
      out << sep << *it;
    }
    out << (is_string_like ? "']" : "]");
  }
  else {
    out << "[]";
  }

  return out;
}

Bây giờ nó khá dễ sử dụng trên mọi phạm vi:

std::cout << range_out{ my_vector };

Kiểm tra giống như chuỗi rời khỏi phòng để cải thiện. Tôi cũng có static_assertkiểm tra trong giải pháp của mình để tránh std::basic_string<>, nhưng tôi để nó ở đây cho đơn giản.


-1

Bạn có thể viết chức năng của riêng bạn:

void printVec(vector<char> vec){
    for(int i = 0; i < vec.size(); i++){
        cout << vec[i] << " ";
    }
    cout << endl;
}

-1

Đối với những người muốn một lớp lót không có vòng lặp:

Tôi không thể tin rằng không có ai nghĩ về điều này, nhưng có lẽ đó là vì cách tiếp cận giống C hơn. Dù sao, nó hoàn toàn an toàn để làm điều này mà không cần một vòng lặp, trong một lớp lót, ĐÁNH GIÁ rằng cái đó std::vector<char>là không kết thúc:

std::vector<char> test { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\0' };
std::cout << test.data() << std::endl;

Nhưng tôi sẽ bọc cái này trong ostreamtoán tử, như @Zorawar đề xuất, để an toàn:

template <typename T>std::ostream& operator<< (std::ostream& out, std::vector<T>& v)
{
    v.push_back('\0'); // safety-check!
    out << v.data();
    return out;
}

std::cout << test << std::endl; // will print 'Hello, world!'

Chúng ta có thể đạt được hành vi tương tự bằng cách sử dụng printfthay thế:

fprintf(stdout, "%s\n", &test[0]); // will also print 'Hello, world!'

GHI CHÚ:

ostreamToán tử quá tải cần chấp nhận vectơ là không const. Điều này có thể làm cho chương trình không an toàn hoặc giới thiệu mã sử dụng sai. Ngoài ra, vì ký tự null được nối thêm, nên việc tái phân bổ std::vectorcó thể xảy ra. Vì vậy, sử dụng vòng lặp for với các vòng lặp có thể sẽ nhanh hơn.


1
1. fprintf(stdout, "%s\n", &test[0]);không khác nhau std::cout << test.data(), cả hai đều yêu cầu một vectơ kết thúc null. 2. "Nhưng tôi sẽ bọc cái này trong toán tử Ostream" << mà sửa đổi toán hạng đúng là một ý tưởng rất tồi.
HolyBlackCat

Tôi đã sử dụng fprintf(stdout, "%s\n", &test[0]);mã trong một thời gian dài mà không gây rắc rối cho tôi. Hấp dẫn! Và tôi đồng ý rằng thật không hay khi sửa đổi vectơ trong ostreamtoán tử, nhưng tôi không thích cả lặp sử dụng các vòng lặp thủ công . Bằng cách nào đó tôi cảm thấy như đối với các hoạt động đơn giản như in một std::vector<char>thư viện tiêu chuẩn sẽ che giấu những thứ này đi. Nhưng C ++ đang phát triển liên tục, nó có thể đến sớm.
ワ イ き
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.