2012-04-07 4 views
0

내가 여기에 "어레이 인터페이스 예"절에 나와있는 예제 코드를 적용하려고 해요 알려져 있지 않은 경우C 프로그램 : 길이가 컴파일 시간

http://orclib.sourceforge.net/doc/html/group_g_bind.html

경우, 문자열의 배열을 설정하는 그들은 장소 사용 OCI_BindArrayOfStrings에 문자열, tab_str의 배열은 : 나는 프로그램이 실행될 때 데이터베이스에서이 길이를 다운로드해야하는 반면

char tab_str[1000][21]; 
... 
OCI_BindArrayOfStrings(st, ":s", (char*) tab_str, 20, 0); 

문제는, 위의 예는, 컴파일시에 배열의 길이를 알고있다.

OCI_BindArrayOfStrings(st, ":s", (char*) my_tab_str, 20, 0); 

내 질문이 my_tab_str을 설정하는 방법이다 : 그래서 my_tab_str라고 문자열 배열을 만들고 다음 코드 줄에 배치하고 싶습니다?

int i, arraysize; 
char person_name[20] = ""; 
char * my_tab_str; 
... 
strncpy(person_name, "John Smith", 19); 
arraysize = <this value is downloaded from database>; 
... 
my_tab_str = malloc(arraysize * sizeof(char) * (strlen(person_name)+1)); 
for(i=0;i<arraysize;i++) { 
    strncpy(my_tab_str[i], person_name, strlen(person_name)); 
} 

목표는의 각 요소에 (내가 컴파일러에 의해 자동으로 추가됩니다 생각) "존 스미스"(예를 들어 10 바이트) 플러스 널 종료 문자를 배치하는 것입니다 : 여기에 (gcc -std=C89를 사용하여 컴파일) 내 코드입니다 캐릭터 라인 배열 my_tab_str 기능 OCI_BindArrayOfStrings 여기에 설명되어 warning: passing argument 1 of 'strncpy' makes pointer from integer without a cast /usr/include/string.h:131: note: expected 'char * __restrict__' but argument is of type 'char'

참고 :

내가 컴파일 경고를 받고 있어요

http://orclib.sourceforge.net/doc/html/group_g_bind.html#ga502cd4785691b17955f5d99276e48884

및 인수로 문자열의 배열을 기대하고있다. 예제 구현에 대해서는 위의 첫 번째 링크에있는 예제 코드를 참조하십시오.

답변

1

귀하의 게시물에서 그 기능이 인수로 기대하는 것은 분명하지 않습니다. 나는 그것이 char **이라고 가정 할 것입니다. 이 경우

, 당신은 같은 것을 할 필요가 :

확인

// Allocate an array of pointers 
char **my_tab_str = calloc(arraysize, sizeof(*my_tab_str)); 

// Allocate room for each string in turn 
for (int i = 0; i < arraysize; i++) { 
    // person_name comes from somewhere 
    const int len = strlen(person_name); 
    my_tab_str[i] = calloc(len+1, sizeof(*my_tab_str[i])); 
    strncpy(my_tab_str[i], person_name, len); 
} 

UPDATE, 즉 함수가 가리키는 char * 걸리는 것 같습니다 있도록 문자열의 수 및 각 문자열의 길이와 함께 연결된 모든 문자열의 연속 1D 배열입니다. 이 경우에, 당신은 이런 식으로 뭔가를해야합니다 :

const int len = strlen(person_name); 

// Big 1D array 
char *my_tab_str = calloc(arraysize*(len+1), sizeof(*my_tab_str)); 

// Put each string into the 1D array, at regular intervals 
for (int i = 0; i < arraysize; i++) { 
    strncpy(&my_tab_str[i*(len+1)], person_name, len); 
} 

이 비록 단지 추측, 그 기능은 정말 잘 문서화하지 않기 때문에.

물론 분명히 어떤 점에서 정리 코드가 필요합니다. free 모두 다.

정말로주의하고 싶다면 각각 calloc에 대한 NULL의 결과를 확인하는 오류 처리 코드를 추가해야하지만 이는 예제를 복잡하게 만들므로 생략했습니다.

+0

좋은 질문 --- 원본 게시글을 'OCI_BindArrayOfStrings'정보로 업데이트했습니다. 첫 번째 링크에 표시된 예제가 의심 할 여지없이 명확 해지기를 바랍니다. 그것들은'(char *)'를 사용하여 그것을 던져 버린 것처럼 보입니다. 그 질문에 대답합니까? – ggkmath

+0

@ggkmath : 흠, 1D 배열의 char이 필요하며 인수로 차원을 제공하는 것 같습니다. 기술적으로, 1D 포인터를 통해 2D 배열에 액세스하는 것은 정의되지 않은 동작입니다. 그러나 몇 분만 주시면 답변을 업데이트하겠습니다 ... –

+0

원래 char ** my_tab_str'을 사용하여 코드를 작성했습니다 (그에 따라 조정 됨) 모든 것이 잘 컴파일됩니다. 하지만 OCILIB가 구문을 실행하려고하면 세그먼트 화 오류가 발생합니다. 나는 그것을 선언 할 때'my_tab_str'을'OCI_BindArrayOfStrings'에 넣으려고하면 행복하지 않다. – ggkmath

2

문자열 배열의 경우 my_tab_str을 char**으로 선언 한 다음 메모리를 할당해야합니다. 그런 다음

my_tab_str = malloc(ROWS * sizeof(char*)); //ROW is no of strings 

,

for(int i=0;i<ROWS;i++) 
my_tab_str[i] = malloc(COLUMNS * sizeof(char)); //COLUMN is the size for each string. 
1

문자열로, 그들은 unsigned char *을 의미하는 것으로 보인다. 이러한 배열을 원하고, 그들은 문자열 배열이 메모리의 연속 블록이다 (약간 이상한) 규칙을 사용하는, 그래서 당신은 그것을 선언 :

unsigned char *my_tab_str; 
size_t namesize = 20; // Better still, use a #define so 20 isn't a mysterious magic number 

그리고 다음과 같이 초기화 :

my_tab_str = malloc(arraysize * sizeof(unsigned char *) * (namesize+1)); // +1 for the null 

for(int i = 0; i < arraysize; ++i) 
    { 
    strncpy(&my_tab_str[i*(namesize+1)], person_name, namesize); 
    } 

첫번째 라인 (malloc에)은 arraysize 문자열 namesize자를위한 공간이 각각 플러스 널위한 충분한 메모리를 할당한다. strncpy은 최대 값이 각각 namesize 바이트이고 그 뒤에 널 ('\ 0')이옵니다. 매번 다음 위치로 포인터를 전달할 때마다 이전 위치보다 namesize+1 바이트가 넘어갑니다.

+0

DRVic 덕분에, 배열'my_tab_str'의 모든 요소는 정확히 똑같습니다 (모두 "John Smith"+ null 문자 포함). 나도 알아,이 이상하게 보일지 모르지만, 그것이 있어야 할 방법입니다. 'char **'를 사용하여 delare하면,'my_tab_str'가'OCI_BindArrayOfStrings'에 입력되는 방식을 변경합니까, 아니면 원래 위에 게시 된 것입니까? – ggkmath

+0

http://stackoverflow.com/questions/4887792/filling-a-string-buffer-when-using-ocilib 필자는 정상적인 규칙대로 스트링 배열을 사용하지 않고 플랫 배열을 사용한다고 언급했다. 답변이 수정되었습니다. – DRVic

+0

위대한 링크를 찾으십시오. 'char' 대신'unsigned char'을 쓰는 이유는 무엇입니까? 'person_name'이 20 바이트를 모두 차지하지 않을 때'namesize'를'strlen (person_name)'으로 대체하여 메모리를 절약 할 수 있습니까? – ggkmath

관련 문제