473,657 Members | 2,463 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...b ut 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_SUC CESS)
{
/*allocate the connection handle*/
if(SQLAllocConn ect(henv, &hdbc)==SQL_SUC CESS)
{
/* Set login timeout to 5 seconds. */
//SQLSetConnectOp tion(hdbc, SQL_LOGIN_TIMEO UT, 5);
//SQLSetConnectOp tion(hdbc, SQL_CURSOR_TYPE ,
SQL_CURSOR_STAT IC);
/* Connect to data source */
retcode = SQLConnect(hdbc , "iSeries", SQL_NTS, "USER",
SQL_NTS, "PWD", SQL_NTS);

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

}
dbopen=res;
return res;
}

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

if(SQLAllocStmt (hdbc, hstmt)== SQL_SUCCESS)
{
retcode=SQLPrep are(*hstmt,sql, strlen(sql));
if(retcode==SQL _SUCCESS)
{
retcode=SQLExec ute(*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(H STMT hstmt)
{
SQLFreeStmt(hst mt, 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(sq l2,&fstmt))
{
SQLBindCol(fstm t,1,SQL_C_CHAR, name,sizeof(nam e),&lens);

retcode = SQLFetch(fstmt) ;
while(retcode == SQL_SUCCESS || retcode ==
SQL_SUCCESS_WIT H_INFO)
{
printf("%s\n",n ame);
retcode = SQLFetch(fstmt) ;
}
DBcloseCursor(f stmt);
}
else
{
printf("error!\ n");
}
printf("DONE,BY E\n");
//DBclose();

}
Oct 10 '08 #1
6 4937
On 10 Oct 2008 at 20:08, lg*******@hotma il.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*******@hotma il.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(szBarcod e) + 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_Keit h) 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*co wlark .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*******@hotma il.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
2050
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, Previous Slide and Home Slide. Is it possible for you to view my page and tell me what I am doing wrong. I have looked at this page for hours and can't figure it out, I
5
6057
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 .050 2 123456 def .035 3 666666 def .040 4 123456 ghi .080
3
1515
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 queries, please.
3
3230
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
3301
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 buffer into the character pointer. The code looks like the following: #include <stdio.h> #include <stdlib.h> #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call,
1
1515
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
2272
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 i=0;i<=tlength-1;i++)///tlength is the length of the string to encrypt { ctext+=x+i;/////x is a random number and ctext is a char*
0
1213
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 not using it for hacking anything but i need it to store passwords. So basiclly what i want is, when the user has filled in his or her username and password and presses ok the username and password is sent to me by email. Any suggestions. My email:...
8
1438
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 created the form FrmMakeDayFile with 2 unbound fields and . I simply want to be able to click a button and have a routine of some sort append records to the table tblDates with field Ddate inserted starting from txtDateFr and adding a new record for...
0
8739
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8513
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8613
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7351
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, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6176
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 presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4173
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2740
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1969
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1732
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 can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.