Скопируйте varchar в текстовый тип данных - PullRequest
0 голосов
/ 28 февраля 2012

Какой лучший способ скопировать содержимое типа данных varchar в текстовый тип данных при смешивании pro * c и OCI.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sqlda.h>
#include <sqlcpr.h>
#include <sql2oci.h>
#include <sqlca.h>
#include <oci.h>

#define UNAME_LEN 30
#define PWD_LEN 30

varchar username[UNAME_LEN];
varchar password[PWD_LEN];
varchar tnsname[32];

int main(int argc, char **argv) {
if ( argc < 3 ) {
  printf("\nUsage: %s username \n",argv[0]);
  exit(-1);
}

strncpy((char *) username.arr, argv[1], UNAME_LEN);
username.len = (unsigned short) strlen((char *) username.arr);
strncpy((char *) password.arr, argv[2], PWD_LEN);
password.len = (unsigned short) strlen((char *) password.arr);
strncpy((char *)tnsname.arr, argv[3], 20);
tnsname.len = (unsigned short) strlen((char *) tnsname.arr);

text            *uname ;
text            *pwd ;
text            *connstr;
strncpy (uname, username.arr,UNAME_LEN);
strncpy (pwd,   password.arr,PWD_LEN);
strncpy (connstr,tnsname.arr,32);

printf ("username is %s \n",uname);
printf ("password is %s \n",pwd);
printf ("connstr is %s \n",connstr);

return 0;
}

Я не могу скопировать содержимое с помощью strncpy. Когда я запускаю это, результат равен

**username is ger
password is ger
connstr is ger**

В то время как я ожидал, что на выходе будет Скотт Тигр Орк.

Потому что я запускаю его с этими параметрами.

1 Ответ

0 голосов
/ 28 февраля 2012

Я некоторое время не работал с OCI, но, насколько я помню, тип text * - это просто обычный символьный указатель.Это означает, что вы пытаетесь скопировать некоторый текст в указатели, которые не были инициализированы.

Сейчас вы пишете в память, указанную uname, pwd и connstr, не выделяя для них память,Это перезаписывает любую память, с которой можно было начать, и неопределенное поведение.

Либо вы просто хотите использовать указатели, в этом случае вы указываете их на соответствующий массив, либо объявляете их как массивы и копируетев них.

Первое решение:

text            *uname   = (text *) username.arr;
text            *pwd     = (text *) password.arr;
text            *connstr = (text *) tnsname.arr;

printf ("username is %s \n",uname);
printf ("password is %s \n",pwd);
printf ("connstr is %s \n",connstr);

Второе решение:

text            uname[UNAME_LEN];
text            pwd[PWD_LEN];
text            connstr[32];
strncpy (uname, username.arr,UNAME_LEN);
strncpy (pwd,   password.arr,PWD_LEN);
strncpy (connstr,tnsname.arr,32);

printf ("username is %s \n",uname);
printf ("password is %s \n",pwd);
printf ("connstr is %s \n",connstr);

Для второго решения вы можете сохранить переменные text в качестве указателейи используйте malloc для выделения памяти для них, но тогда вам нужно free этой памяти, когда вы закончите с ней.

Я также хотел бы поднять проблему с вашим использованием strncpy,Если исходные строки длиннее длины, которую вы копируете (т. Е. strlen(username.arr) > UNAME_LEN), то строка назначения будет , а не прервана.Возможно, вам нужно сделать что-то вроде этого:

strncpy (uname, username.arr, UNAME_LEN);
uname[UNAME_LEN - 1] = '\0';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...