473,503 Members | 13,381 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Need beginner help with C (LabWindows/CVI)!

First of all, please forgive my newness to the language. I have had
much experience programming...but not in C! :)

I am modifying a program designed in LabWindows/CVI, which as far as I
can tell is a version of ANSI C. The program needs to communicate
with my AS/400 via sql/odbc to retrieve some information about a
barcode scanned part.

This works. Once. After that, it blows up on the SQLPrepare
command. I have no idea why, and I really don't understand where I've
failed. Any guidance would be greatly appreciated as I try to learn
this language in a matter of days to complete this project... >_<

Below you will find the procedures that I have added for the AS400
connection, per research I did online. In the opening process of the
program it calls DBopen. Then, I am simulating a barcode scan by
calling a procedure TestAS400. It asks for a barcode label and then
uses that in a dynamic sql statement. As I said, this works the first
time. The first time I get the following output:
--------------------------
[data]
DONE,BYE
--------------------------
The second time I get the last 15 characters of the sql statement
followed by 'Error or SQLPrepare!!', then "error!', then "DONE,BYE".

I just don't get it! Is my connection not being closed properly? How
do I fix this? Any ideas are very much appreciated.

Oh, and even though I only wanted one field returned from my sql
statement, I had to make the statement ask for two or my variable
would be corrupted?! I really am being tossed in to this. Sorry if
these are newbie errors.

Procedures:
--------------------------
int DBopen(void)
{
int res=0;
RETCODE retcode;

printf("DBopen Start\n");

/*allocate the environment handle*/
if(SQLAllocEnv(&henv)==SQL_SUCCESS)
{
/*allocate the connection handle*/
if(SQLAllocConnect(henv, &hdbc)==SQL_SUCCESS)
{
/* Set login timeout to 5 seconds. */
//SQLSetConnectOption(hdbc, SQL_LOGIN_TIMEOUT, 5);
//SQLSetConnectOption(hdbc, SQL_CURSOR_TYPE,
SQL_CURSOR_STATIC);
/* Connect to data source */
retcode = SQLConnect(hdbc, "iSeries", SQL_NTS, "USER",
SQL_NTS, "PWD", SQL_NTS);

if (retcode == SQL_SUCCESS || retcode ==
SQL_SUCCESS_WITH_INFO)
{
res=1;
}
}
else
{
SQLFreeConnect(hdbc);
}
}
else
{
SQLFreeEnv(henv);

}
dbopen=res;
return res;
}

void DBclose(void)
{
if(dbopen)
{
SQLDisconnect(hdbc);
SQLFreeConnect(hdbc);
SQLFreeEnv(henv);
}
dbopen=0;
}
int DBexecute(char *sql,HSTMT *hstmt)
{
int res=0;
RETCODE retcode;

if(SQLAllocStmt(hdbc, hstmt)== SQL_SUCCESS)
{
retcode=SQLPrepare(*hstmt,sql,strlen(sql));
if(retcode==SQL_SUCCESS)
{
retcode=SQLExecute(*hstmt);
if(retcode==SQL_SUCCESS)
{
res=1;
}
else
{
printf("Error on SQLExecute!!\n");
}
}
else
{
printf(sql);
printf("Error on SQLPrepare!!\n");
}
}
else
{
printf("Error on SQLAllocStmt!!\n");
}
return res;
}

void DBcloseCursor(HSTMT hstmt)
{
SQLFreeStmt(hstmt, SQL_DROP);
}

void TestAS400()
{
char sql[160];
char *sql2;
HSTMT fstmt;
long lens;
RETCODE retcode;
char name[2 + 1];
char szBarcode[13 + 1];

scanf("%s", szBarcode );

sql2 = strcat("SELECT field1,field2 FROM library.file where field3 =
(select field4 from library.file where field5 ='",szBarcode);
sql2 = strcat(sql2,"')\n");

if(DBexecute(sql2,&fstmt))
{
SQLBindCol(fstmt,1,SQL_C_CHAR,name,sizeof(name),&l ens);

retcode = SQLFetch(fstmt);
while(retcode == SQL_SUCCESS || retcode ==
SQL_SUCCESS_WITH_INFO)
{
printf("%s\n",name);
retcode = SQLFetch(fstmt);
}
DBcloseCursor(fstmt);
}
else
{
printf("error!\n");
}
printf("DONE,BYE\n");
//DBclose();

}
Oct 10 '08 #1
6 4932
On 10 Oct 2008 at 20:08, lg*******@hotmail.com wrote:
void TestAS400()
{
char sql[160];
char *sql2;
HSTMT fstmt;
long lens;
RETCODE retcode;
char name[2 + 1];
char szBarcode[13 + 1];

scanf("%s", szBarcode );

sql2 = strcat("SELECT field1,field2 FROM library.file where field3 =
(select field4 from library.file where field5 ='",szBarcode);
sql2 = strcat(sql2,"')\n");
This is very bad news. Firstly, sql2 could be pointing anywhere - you
need to allocate memory before you can write to it. Secondly, strcat()
doesn't behave the way you think it does.

Try:

sql2 = malloc(snprintf(NULL, 0,
"SELECT field1,field2 FROM library.file where field3 = "
"(select field4 from library.file where field5 ='%s')\n", szBarcode)+1);
if(sql2)
sprintf(sql2,
"SELECT field1,field2 FROM library.file where field3 = "
"(select field4 from library.file where field5 ='%s')\n", szBarcode);
else
/* handle error */

Then remember to free(sql2); when you're done with it.

Oct 10 '08 #2
lg*******@hotmail.com writes:
[...]
void TestAS400()
{
char sql[160];
char *sql2;
HSTMT fstmt;
long lens;
RETCODE retcode;
char name[2 + 1];
char szBarcode[13 + 1];

scanf("%s", szBarcode );
This reads one whitespace-delimited "word" from stdin and stores it in
szBarcode. You normally have no control over what appears on stdin.
What if the word you read is bigger than what szBarcode can hold? Use
a length specifier rather than a bare "%s" format to avoid this.
Better, read input a line at a time and then process it.
sql2 = strcat("SELECT field1,field2 FROM library.file where field3 =
(select field4 from library.file where field5 ='",szBarcode);
sql2 = strcat(sql2,"')\n");
[...]

Your strcat() calls are certainly a problem. Whether they explain the
symptoms you're seeing is another matter.

strcat() takes two char* arguments, both of which must point to
strings. A copy of the contents of the string pointed to by the
second argument is appended to the end of the string pointed to by the
first argument.

This means that (a) the first string needs to be writable, and (b)
there must be enough room to store the result.

A string literal may or may not be writable, depending on your
implementation, but in any case attempting to write to it invokes
undefined behavior. (Note that this *might* mean that it behaves as
you expect it to.) Either way, a string literal does not allocate any
additional space beyond what's needed for the string itself (including
the terminating '\0'), so you're also attempting to write over memory
that you haven't allocated.

Here's how I might do it:

char *sql2;
const char command[] = "SELECT field1,...";
...
sql2 = malloc(sizeof command + strlen(szBarcode) + 1);
/* Check whether sql2==NULL */
strcpy(sql2, command);
strcat(sql2, szBarcode);

You'll need to check whether malloc succeeded before attempting to use
the result, which means you'll need to decide what to do if it fails;
aborting the program with an error message is probably better than
ignoring the error.

I haven't gone over your code thoroughly, so there may be other
errors; this one just jumped out at me.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 10 '08 #3
Antoninus Twink wrote:
[...]
sql2 = malloc(snprintf(NULL, 0,
"SELECT field1,field2 FROM library.file where field3 = "
"(select field4 from library.file where field5 ='%s')\n", szBarcode)+1);
if(sql2)
sprintf(sql2,
"SELECT field1,field2 FROM library.file where field3 = "
"(select field4 from library.file where field5 ='%s')\n", szBarcode);
else
/* handle error */
Just as an addendum to what Antoninus posted, if you don't care about
portability (and it looks like you're a Windows programmer), look to see
if your platform has an aprintf() function (sometimes called
asprintf()). Most libcs have an extension that does this. What it is is
an sprintf() that will return you a newly allocated block of the right
size, which means you avoid having to allocate it yourself (and
therefore avoid getting it wrong). While it's not terribly efficient, it
can make string handling code much, much easier to get right.

If you *don't* have one, or you do care about portability, you may want
to consider writing your own.
Then remember to free(sql2); when you're done with it.
You still need to do this with aprintf(), though.

--
┌─── dg*cowlark.com ───── http://www.cowlark.com ─────
│ "...it's not that well-designed GUI's are rare, it's just that the
│ three-armed users GUI's are designed for are rare." --- Mike Uhl on
│ a.f.c
Oct 10 '08 #4
Great! Thanks everyone for the awesome help! I'll put these newly-
learned points to use today.

I do have one more quick dummy question though about what I've seen
here. Sometimes I notice ints and chars defined with an asterisk. I
have not had much success searching online for information on what
that means exactly. Is there either 1) any quick and dirty reference
that you could point me to that would explain such simple things to
me, or 2) just explain in 7,204^2 words or less what exactly the
significance of the * is? <G>

Thanks! I really appreciate your kind assistance!!

Oct 13 '08 #5
lg*******@hotmail.com said:
Great! Thanks everyone for the awesome help! I'll put these newly-
learned points to use today.

I do have one more quick dummy question though about what I've seen
here. Sometimes I notice ints and chars defined with an asterisk. I
have not had much success searching online for information on what
that means exactly. Is there either 1) any quick and dirty reference
that you could point me to that would explain such simple things to
me, or 2) just explain in 7,204^2 words or less what exactly the
significance of the * is? <G>
In a definition (or declaration), * means "pointer to". Thus:

int i = 42; /* i is an int */
int j = 0;
int *p; /* p is a pointer to int; *p is an int */

p = &i; /* p now points to i */
j = *p; /* j now has the value 42, i.e. the value of the thing
to which p points */
*p = 6; /* i's value has now been changed to 6 */

For further information on pointers, consult your C reference.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 13 '08 #6
Thanks for the quick notes, and thanks everyone for your comments and
help! I know a lot more now because of such assistance, and now I
think I can hit the ground running!

I made the some of the changes that were offered and have been having
perfect success retrieving the data I wanted! THANK YOU!
Oct 14 '08 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2043
by: TrvlOrm | last post by:
HI There, I have been struggling with JavaScript code for days now, and this is my last resort! Please help... I am trying to create a JavaScript slide show with links for Next Slide,...
5
6046
by: Jim | last post by:
Need help with aggregate function...for each unique product, I need the provider with the cheapest cost factor Here't the table (Table1) ID product provider factor 1 123456 abc...
3
1507
by: Susan | last post by:
Customer Orders are ranked from 1 to 10 and are assigned an order type of 1, 2 or 3. The table for this is: TblOrderRankType OrderRankTypeID CustomerID Rank Type I need help with two...
3
3220
by: bob | last post by:
Need help with c macro. Have this call in my c program. stub.c SYMBOL(ALPHA) << no, dont want to change this to any other form. SYMBOL(BETA) Need a macro to expand each of above to this.
7
3287
by: Timothy Shih | last post by:
Hi, I am trying to figure out how to use unmanaged code using P/Invoke. I wrote a simple function which takes in 2 buffers (one a byte buffer, one a char buffer) and copies the contents of the byte...
1
1508
by: jun qu | last post by:
I just make my first C# test application, my question is what file such as DLL need along with this exe, when install exe at another computer. Thanks
10
2257
by: Nemok | last post by:
Hi, I am trying to write an additive encryption algorithm in C++ that will encrypt a text by adding a random numer to each character in a string. The code looks similar to this: for(int...
0
1206
by: shangardezi | last post by:
hi im a beginner with visual basic. I was wondering can someone tell me how i can somehow do a thing that when someone presses ok on the LOGIN FORM, the username and password is sent to my email. im...
8
1424
by: mvdave | last post by:
Hello all & I hope I'm posting in the right place.. I need to load a temporary table with a range of sequential dates, passing it a beginning and an end date from a criteria form. I have...
0
7213
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
1
7017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5610
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing,...
1
5026
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4698
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3187
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3176
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
754
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
406
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.