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
).
이 경우 typedef
C ++ 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_type
이 size
있습니다. 메소드가 리턴 한 유형 입니다.
// 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
.