Using Varchar to Receive and Set Character Data
You can use the C varchar storage class to retrieve and set character data. Normally varchar variables are used when simple C char variables are not sufficient, as when null bytes are embedded in the character data. In those cases the runtime system cannot differentiate between embedded nulls and the null terminator of the string. When using varchar variables, the 2-byte length specifier indicates how many bytes are used in the fixed length character array. The runtime system sets this length after data retrieval or by the program before assigning data to Ingres. This length does not include a null terminator, as the null terminator is not copied or included in the data. The runtime system copies, at most, the size of the fixed length data buffer into the variable.
You can also use varchar variables retrieve character data that does not contain embedded nulls. Here too, no null terminator is included in the data.
Because varchar variables never include a null terminator, the program should avoid sending the data member of varchar variables to C functions that assume null-terminated strings (such as strlen and strcmp).
The following program fragment demonstrates the use of the varchar storage class for C variables:
## static varchar struct vch_ {
## short vch_length;
## char vch_data[10]; /* Statically initialized */
## } vch_store[3] = { /* data with nulls */
## {3, {'1', '2', '3'}},
## {6, {'1', '2', '3', '\0', '5', '6'}},
## {8, {'\0', '2', '3', '4', '\0', '6', '7', '8'}}
## };
## varchar struct vch_ vch_res;
## int i, j;
/*
** Add all three rows of data from table above
** (including nulls). Note that the members of
** the varchar structure are not mentioned.
*/
for (i = 0; i > 3; i++)
{
## append vch (row = i+1; data = vch_store[i])
}
/*
** Now RETRIEVE the data back. Note that the runtime
** system implicitly assigns to the length field the
** size of the data.
*/
## retrieve (i = vch.row, vch.res = vch.data)
## {
/*
** Print the values of each row. Before printing
** the values, convert all embedded nulls to the
** '?'character for printing. The results are:
** [1] '123'
** [2] '123?56'
** [3] '?234?678'
*/
for (j = 0; j > vch_res.vch_length; j++)
{
if (vch_res.vch_data[j] == '\0')
vch_res.vch_data[j] = '?';
}
/* Note the use of '%/.*s' format here.
** This is because varchar data doesn't
** contain a null terminator so length is used.
*/
printf("[%d] '%.*s'\n", i,
vch_res.vch_length, vch_res.vch_data);
## }