카테고리 보관물: C++

C++

벡터의 내용을 인쇄하는 방법? 벡터의 내용을 인쇄하고 싶습니다. 다음은

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;
    }
}

벡터의 내용을 화면에 어떻게 인쇄합니까?



답변

순수하게 질문에 대답하기 위해 반복자를 사용할 수 있습니다.

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

for 루프에서 벡터의 내용을 수정하려면 iterator대신const_iterator .

그러나 이것에 대해 말할 수있는 것이 더 많이 있습니다. 당신이 사용할 수있는 대답을 원한다면 여기서 멈출 수 있습니다. 그렇지 않으면 계속 읽으십시오.

자동 (C ++ 11) / typedef

이것은 다른 해결책이 아니라 위의 iterator해결책에 대한 보충 입니다. C ++ 11 표준 (이상)을 사용하는 경우 auto키워드를 사용 하여 가독성을 높일 수 있습니다 .

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

그러나의 유형은 i상수가 아닙니다 (즉, 컴파일러는 std::vector<char>::iterator의 유형으로 사용합니다 i).

이 경우 typedefC ++ 11에 국한되지 않고 어쨌든 사용하는 것이 매우 유용합니다.

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

카운터

물론 정수 유형을 사용하여 for루프 에서 위치를 기록 할 수 있습니다 .

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

이 작업을 수행하려는 경우 컨테이너의 멤버 유형이 사용 가능하고 적절하다면 사용하는 것이 좋습니다. 이 작업에 대한 std::vector멤버 유형 size_typesize있습니다. 메소드가 리턴 한 유형 입니다.

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

iterator솔루션 보다 이것을 사용하지 않습니까? 간단한 경우도 가능하지만 요점은 iterator클래스 가이 솔루션이 이상적이지 않은보다 복잡한 객체를 위해이 작업을 수행하도록 설계된 객체라는 것입니다.

범위 기반 for 루프 (C ++ 11)

Jefffrey의 솔루션을 참조하십시오 . C ++ 11 이상에서는 for다음과 같은 새로운 범위 기반 루프를 사용할 수 있습니다 .

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

이후 path항목 (명시 적으로의 벡터이다 std::vector<char>), 객체가 i벡터의 항목의 유형입니다 (즉, 명시 적으로,이 유형이다 char). 개체 i는 개체 의 실제 항목의 복사 본인 값을 갖습니다 path. 따라서 i루프의 모든 변경 사항 path자체 는 유지되지 않습니다 . 또한 i루프에서 복사 된 값을 변경하고 싶지 않다는 사실을 적용 하려면 유형 i을 다음 const char과 같이 강제 설정할 수 있습니다 .

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

의 항목을 수정하려면 path참조를 사용할 수 있습니다.

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

그리고 수정하고 싶지 않더라도 path객체 복사가 비싼 경우 값으로 복사하는 대신 const 참조를 사용해야합니다.

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

표준 :: 복사

참조 여호수아의 대답을 . STL 알고리즘 std::copy을 사용하여 벡터 내용을 출력 스트림에 복사 할 수 있습니다 . 이것은 편안하다면 우아한 솔루션입니다 (그리고 벡터의 내용을 인쇄하는 경우뿐만 아니라 매우 유용합니다).

std :: for_each

Max의 솔루션을 참조하십시오 . 사용 std::for_each이 간단한 시나리오에 대한 잔인한 사람이지만, 그냥 화면으로 인쇄하는 것보다 더 많은 일을하기를 원한다면 매우 유용한 솔루션입니다 : 사용 std::for_each당신이 할 수 있는 벡터 내용에 (분별) 작업을.

과부하 ostream :: operator <<

Chris의 답변을 참조하십시오 . 오버로드에서 위의 솔루션 중 하나를 여전히 구현해야하기 때문에 이것은 다른 답변에 대한 보완입니다. 그의 예제에서 그는 for루프 에서 카운터를 사용했습니다 . 예를 들어 다음과 같이 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;
}

다른 솔루션의 사용법은 간단해야합니다.

결론

여기에 제시된 모든 솔루션이 작동합니다. “최고”의 코드는 사용자에게 달려 있습니다. 이것보다 더 자세한 것은 아마도 찬반 양론이 적절하게 평가 될 수있는 또 다른 질문에 가장 적합한 것입니다. 그러나 항상 사용자 환경 설정이 항상 역할을합니다. 제시된 솔루션 중 어느 것도 잘못되지 않지만 일부는 각 개별 코더에 더 좋아 보일 것입니다.

추가

이것은 내가 게시 한 이전 솔루션의 확장 솔루션입니다. 그 게시물이 계속 주목을 받고 있기 때문에 나는 그것을 확장하기로 결정하고 여기에 게시 된 다른 우수한 솔루션을 참조하기로 결정했습니다. 내 원래의 게시물은 경우 그 언급 한 발언했다 있었다 , 안쪽 당신의 벡터 수정에 대한 의도 for다음이에서 제공하는 두 가지 방법이 있습니다 루프 std::vector: 액세스 요소에 std::vector::operator[]범위 검사를하지 않으며 std::vector::at않는 범위 검사를 수행. 즉, at벡터 외부의 요소에 액세스하려고 시도하면 operator[]그렇지 않습니다. 나는 누군가가 이미 모르는 경우에 유용 할 수있는 것을 언급하기 위해 원래이 의견을 추가했다. 그리고 나는 지금 아무런 차이가 없습니다. 따라서이 부록은 다음과 같습니다.


답변

가장 쉬운 방법은 표준 복사 알고리즘을 사용하는 것입니다 .

#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는 반복자 어댑터 입니다. 스트림 (이 경우에는 char) 으로 인쇄하기 위해 유형 위에 템플릿 화 됩니다. cout(일명 콘솔 출력)은 우리가 쓰려는 스트림과 공백 문자 (" " )는 벡터에 저장된 각 요소 사이에 인쇄하려는 것입니다.

이 표준 알고리즘은 강력하며 다른 알고리즘도 강력합니다. 표준 라이브러리가 제공하는 강력 함과 유연성이 그토록 큰 장점입니다. 단지 줄의 코드로 콘솔에 벡터를 인쇄 할 수 있습니다 . 구분 문자를 사용하여 특별한 경우를 처리 할 필요는 없습니다. for 루프에 대해 걱정할 필요가 없습니다. 표준 라이브러리는 모든 것을 지원합니다.


답변

C ++ 11에서는 이제 범위 기반 for 루프를 사용할 수 있습니다 .

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

답변

이 작업을 수행하는 가장 좋은 방법은 operator<<이 기능을 프로그램에 추가하여 오버로드 하는 것입니다.

#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;
}

그런 다음 <<요소도 ostream& operator<<정의 했다고 가정하면 가능한 벡터 에서 연산자를 사용할 수 있습니다 .

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;

출력 :

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

답변

방법에 대한 for_each+의 람다 식 :

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

물론 범위 기반 은이 구체적인 작업을위한 가장 우아한 솔루션이지만이 방법은 다른 많은 가능성을 제공합니다.

설명

for_each알고리즘은 얻어 입력 범위호출 객체 의 범위의 모든 요소에서이 오브젝트를 호출. 입력 범위가 2로 정의 반복자 . 호출 객체 함수 함수 포인터, 과부하 클래스의 객체 일 수 () operator또는 이러한 경우에서와 같이, 람다 식 . 이 표현식의 매개 변수는 벡터의 요소 유형과 일치합니다.

이 구현의 장점은 람다 식에서 얻을 수있는 힘입니다. 벡터를 인쇄하는 것보다 훨씬 더 많은 방법으로이 방법을 사용할 수 있습니다.


답변

컨테이너를 콘솔에 복사하십시오.

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

출력해야합니다 :

1 2 3 4

답변

문제는 아마도 이전 루프에있을 것입니다 : (x = 17; isalpha(firstsquare); x++). 이 루프는 전혀 실행되지 않거나 ( firstsquare알파가 아닌 경우 ) 영원히 실행됩니다 (알파인 경우). 그 이유는 증가 firstsquare함에 따라 변경되지 않기 때문입니다 x.