C ++에서 문자열 배열을 선언하는 방법은 무엇입니까?


89

가능한 최선의 방법으로 정적 문자열 배열의 모든 요소를 ​​반복하려고합니다. 한 줄에 선언하고 번호를 추적하지 않고도 요소를 쉽게 추가 / 제거 할 수 있기를 원합니다. 정말 간단하게 들리지 않습니까?

가능한 비 해결 방법 :

vector<string> v;
v.push_back("abc");
b.push_back("xyz");

for(int i = 0; i < v.size(); i++)
    cout << v[i] << endl;

문제-문자열 목록으로 한 줄에 벡터를 생성하는 방법이 없습니다.

가능한 비 해결 방법 2 :

string list[] = {"abc", "xyz"};

문제-문자열 수를 자동으로 가져올 수있는 방법이 없습니다 (내가 알고있는).

이 작업을 수행하는 쉬운 방법이 있어야합니다.


부스트 할당 라이브러리는 당신이 찾고있는 정확하게 것 같다. 컨테이너에 상수를 그 어느 때보 다 쉽게 할당 할 수 있습니다.
Craig H

답변:


108

C ++ 11은 다음 구문을 허용하는 초기화 목록을 추가했습니다.

std::vector<std::string> v = {"Hello", "World"};

이 C ++ 11 기능에 대한 지원은 GCC 4.4 이상 및 Visual Studio 2013 에서만 추가되었습니다 .


2018. 방금 C ++를 시작하고 유연한 배열에 대해 꽤 많은 연구를했습니다. 단지 벡터를 사용하여 종료 ...
로버트 몰리나

37

vector<string>정적으로 생성 된 char*배열 에서를 간결하게 초기화 할 수 있습니다 .

char* strarray[] = {"hey", "sup", "dogg"};
vector<string> strvector(strarray, strarray + 3);

그건 그렇고 모든 문자열을 복사하므로 두 배의 메모리를 사용합니다. Will Dean의 제안을 사용하여 여기서 매직 넘버 3을 arraysize (str_array)로 대체 할 수 있습니다. 특정 버전의 arraysize가 뭔가 나쁜 일을 할 수있는 특별한 경우가 있음을 기억하지만 (미안하지만 즉시 세부 사항을 기억할 수 없습니다) . 그러나 매우 자주 올바르게 작동합니다.

또한 한 줄에 대해 정말 쿵호라면 가변 매크로를 정의하여 한 줄이 DEFINE_STR_VEC(strvector, "hi", "there", "everyone");작동 하도록 할 수 있습니다 .


strarray헤더에 있기 때문에 하나의 정의 규칙을 위반하지 않습니까?
jww

22

문제-문자열 수를 자동으로 가져올 방법이 없습니다 (내가 알고있는).

많은 사람들 (MS 포함)이 다음과 같은 매크로를 정의하는 늪지 표준 방법이 있습니다 arraysize.

#define arraysize(ar)  (sizeof(ar) / sizeof(ar[0]))

1
: 또한, 하나는 다음과 같이 사용할 수 있습니다 template<typename T, size_t N> inline size_t arraysize(T (&ar)[N]) { return N; } .. (인라인 저는 믿습니다 필요하지 키워드,하지만 기능의 의도 현대 컴파일러는 이론적으로 전체 기능을 반환 할 수 있어야한다 문서화하는 데 사용
저스틴 시간 - 분석 재개 모니카

1
이것은 포인터에 대해 실패합니다. 배열 요소 계산은 C ++에서 다른 방식으로 수행되어야합니다.
jww

8

다음과 같이 C ++에서 문자열 배열을 선언합니다. char array_of_strings[][]

예 : char array_of_strings[200][8192];

각 문자열의 크기는 8kb 또는 8192 바이트입니다.

strcpy(line[i],tempBuffer); 문자열 배열에 데이터를 넣는 데 사용 합니다.


참고로, char array_of_strings [] []는 C ++ 문자열을 허용 할 수 없습니다. 먼저 char *로 변환해야합니다. cplusplus.com/reference/string/string/c_str
Luqmaan

array_of_strings헤더에 있기 때문에 하나의 정의 규칙을 위반하지 않습니까?
jww

7

한 가지 가능성은 NULL 포인터를 플래그 값으로 사용하는 것입니다.

const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
    cout << *iList;
}

char **는 실제로 무엇을 의미합니까? 자바에서는 문자열 목록일까요?
IAmGroot

1
@Doomsknight :이 경우에는 그렇습니다. 첫 번째 줄에서 나는 배열을 정의합니다 char*. 메모리에서 이것은 3 개의 포인터로 배치됩니다. 하나는 "개"를 가리키고 하나는 "고양이"를 가리키고 하나는 NULL로 남습니다. 첫 번째 포인터에 대한 포인터를 가져 와서 char**char에 대한 포인터에 대한 포인터를 얻을 수 있습니다. 이 값을 증가 시키면 목록의 다음 항목 ( "cat"을 가리키는 포인터에 대한 포인터)을 가리 키도록 char **을 이동 한 다음 다시 증가하고 NULL 포인터를 가리키는 포인터를 가져옵니다. 내가 끝났다는 걸 알아. (
Eclipse

4

Boost 범위 라이브러리 의 beginend함수를 사용하여 기본 배열의 끝을 쉽게 찾을 수 있으며, 매크로 솔루션과 달리 실수로 포인터에 적용하면 잘못된 동작 대신 컴파일 오류가 발생합니다.

const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));

3

Will Dean의 제안 [ #define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))]을 사용하여 여기서 매직 넘버 3을 arraysize (str_array)로 바꿀 수 있습니다. 특정 버전의 arraysize가 뭔가 나쁜 일을 할 수있는 특별한 경우가 있다는 것을 기억하지만 (죄송합니다. 바로). 그러나 매우 자주 올바르게 작동합니다.

작동하지 않는 경우는 "배열"이 실제 배열이 아니라 실제로 포인터 일 때입니다. - 방식의 배열이 (첫 번째 요소에 대한 포인터로 변환) 함수에 전달되기 때문에 또한, 그것은 작동하지에서 작업 배열과 같은 서명 보이는 경우에도 호출하지 some_function(string parameter[])정말 some_function(string *parameter).


3

예를 들면 다음과 같습니다.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main() {
    const char* const list[] = {"zip", "zam", "bam"};
    const size_t len = sizeof(list) / sizeof(list[0]);

    for (size_t i = 0; i < len; ++i)
        std::cout << list[i] << "\n";

    const std::vector<string> v(list, list + len);
    std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));
}

2

해당 매크로 대신 다음을 제안 할 수 있습니다.

template<typename T, int N>
inline size_t array_size(T(&)[N])
{
    return N;
}

#define ARRAY_SIZE(X)   (sizeof(array_size(X)) ? (sizeof(X) / sizeof((X)[0])) : -1)

1) 매크로를 사용하여 컴파일 시간 상수로 만들고 싶습니다. 함수 호출의 결과는 컴파일 타임 상수가 아닙니다.

2) 그러나 매크로가 실수로 포인터에 사용될 수 있기 때문에 매크로를 사용하고 싶지 않습니다. 이 함수는 컴파일 타임 배열에서만 사용할 수 있습니다.

따라서 우리는 매크로를 "안전"하게 만들기 위해 함수의 정의성을 사용합니다. 함수가 존재하는 경우 (즉, 크기가 0이 아닌 경우) 위와 같이 매크로를 사용합니다. 함수가 존재하지 않으면 잘못된 값을 반환합니다.


2
#include <boost/foreach.hpp>

const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
    cout << str << endl;
}

1
#include <iostream>
#include <string>
#include <vector>
#include <boost/assign/list_of.hpp>

int main()
{
    const std::vector< std::string > v = boost::assign::list_of( "abc" )( "xyz" );
    std::copy(
        v.begin(),
        v.end(),
        std::ostream_iterator< std::string >( std::cout, "\n" ) );
}

1

같은 문자열 배열을 직접 선언 할 수 있습니다 string s[100];. 그런 다음 특정 요소에 액세스하려면 s[2][90]. 반복을 위해 s[i].size()함수를 사용하여 문자열 크기를 가져옵니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.