El empleo del lenguaje C++

Transcripción

El empleo del lenguaje C++
Aplicaciones C++
Ejemplos selectos de aplicaciones ILE C/C++ (System i)
Pantalla con menú de edición clientes.
CLIENTEP.CPP Programa.
CLIENTES.DSPF Pantalla.
Creación y manipulación de ventanas.
CRTMNMWND.C Programa.
Uso del control de compromiso.
CTRCOMMITC.CLLE Programa llamador.
CTRCOMMITP.CPP Programa llamado.
CTRCOMMITS.DSPF Pantalla.
Uso de subficheros.
SUBFILEP.CPP Programa.
SUBFILES.DSPF Pantalla.
Operaciones archivo con valores _DecimalT.
WRITINGDEC.CPP Programa
Tabla de usuarios (se usa en CTRCOMMIT y SUBFILE)
USUARIOSF.PF Definición del archivo
USUARIOSD.SQL Datos de test
Comandos básicos en ILE C/C++ (System i)
/* Crear Programa C++ Enlazado (CRTBNDCPP) */
CRTBNDCPP
PGM(&L/&N)
SRCFILE(&L/&F)
SRCMBR(&N)
OUTPUT(*PRINT)
OPTION(*SHOWSRC)
DBGVIEW(*SOURCE)
REPLACE(*YES)
/* Generar fuente en C/C++ (GENCSRC) */
/* Recupera información de un archivo descrito */
/* externamente para su uso en C/C++ */
GENCSRC
OBJ('/QSYS.LIB/&L.LIB/&N.FILE')
SRCFILE(&L/&F)
SRCMBR(&N.H)
Página 1
Documento: CLIENTEP.CPP
// CLIENTEP.CPP
| Ejemplo pantalla con menu de edicion clientes
// ILE C/C++ (System i)
/*
* Este programa utiliza indicadores de respuesta para notificar al programa
* que F3/F12 ha sido pulsado por el usuario para determinar que una solicitud
* de entrada ha terminado.
* Los indicadores de respuesta se devuelven en un area de indicadores separada.
*/
#include <recio.h>
#include <decimal.h>
#include <iostream>
#include <string>
using namespace std;
#define IND_ON '1'
#define IND_OFF '0'
//
#define F0 -1
#define F3
2
#define F6
5
#define F10 9
#define F12 11
// Prototipos de funciones de uso general
_ConvertDecimal ZtoD(char *, int, int);
string CtoS(char *, int);
void DtoZ(_ConvertDecimal, char *);
void StoC(string, char *, int);
// Prototipo para nuevos clientes
int nuevo_cliente(_RFILE *, _SYSindara);
//
typedef struct {
char MNUCHOICE[2];
/* ESPECIFICADO CON ZONA EN DDS - SUSTITUIDO POR TIPO CARACTER */
char PULLINPUT[2];
/* ESPECIFICADO CON ZONA EN DDS - SUSTITUIDO POR TIPO CARACTER */
} r_menu;
typedef struct {
char NOMBRE[30];
char DIRECCION[30];
char LOCALIDAD[30];
char CONTACTO[30];
char TELEFONO[9];
/* ESPECIFICADO CON ZONA EN DDS - SUSTITUIDO POR TIPO CARACTER */
char EMAIL[30];
char INGRESOS[15];
/* ESPECIFICADO CON ZONA EN DDS - SUSTITUIDO POR TIPO CARACTER */
char FECHA[8];
/* CAMPO DATE - DATFMT(*DMY) DATSEP('/') */
char HORA[8];
/* CAMPO TIME - TIMFMT(*HMS) TIMSEP(':') */
} r_cliente;
// Variables publicas (datos del cliente)
string
nombre
= "";
string
direccion = "";
string
localidad = "";
string
contacto = "";
decimal( 9, 0) telefono = 0 ;
string
email
= "";
decimal(15, 2) ingresos = 0 ;
string
fecha
= "";
string
hora
= "";
int main (void) {
_RFILE *fp;
_SYSindara ind;
_RIOFB_T *rfb;
r_menu menu;
if ((fp = _Ropen ("CLIENTES", "ar+ indicators=y")) == NULL) {
cout << "Fallo en la apertura del fichero de pantalla\n";
exit(1);
Página 2
Documento: CLIENTEP.CPP
}
_Rindara(fp, ind);
decimal(2,0) menupri = 0;
decimal(2,0) submenu = 0;
DtoZ(menupri, menu.MNUCHOICE);
DtoZ(submenu, menu.PULLINPUT);
do {
_Rformat(fp, "APPSCR");
rfb = _Rwrite(fp, &menu, sizeof(menu));
rfb = _Rreadn(fp, &menu, sizeof(menu), __DFT);
menupri = ZtoD(menu.MNUCHOICE, sizeof(menu.MNUCHOICE), 0);
submenu = ZtoD(menu.PULLINPUT, sizeof(menu.PULLINPUT), 0);
// Nuevo
if((menupri == 1 && submenu == 1) || (ind[F6] == IND_ON)) {
int opc_cli = nuevo_cliente(fp, ind);
if((opc_cli == F3) || (opc_cli == F12) ) { // El usuario ha pulsado F3/F12
;
} else {
// En otro caso
;
}
// Salir
} else if((menupri == 1 && submenu == 6) ||
(ind[F3] == IND_ON) || (ind[F12] == IND_ON)) {
break;
}
} while(true);
// Restauramos pantalla previa y salimos
_Rformat(fp, "RMVWDW");
rfb = _Rwrite(fp, "", 0);
_Rclose (fp);
return 0;
}
int nuevo_cliente(_RFILE *fp,
_RIOFB_T *rfb;
r_cliente cliente;
_SYSindara ind) {
_Rformat(fp, "WDW01");
StoC(nombre,
cliente.NOMBRE,
StoC(direccion, cliente.DIRECCION,
StoC(localidad, cliente.LOCALIDAD,
StoC(contacto, cliente.CONTACTO,
DtoZ(telefono, cliente.TELEFONO
StoC(email,
cliente.EMAIL,
DtoZ(ingresos, cliente.INGRESOS
StoC(fecha,
cliente.FECHA,
StoC(hora,
cliente.HORA,
sizeof(cliente.NOMBRE)
);
sizeof(cliente.DIRECCION));
sizeof(cliente.LOCALIDAD));
sizeof(cliente.CONTACTO) );
);
sizeof(cliente.EMAIL)
);
);
sizeof(cliente.FECHA)
);
sizeof(cliente.HORA)
);
rfb = _Rwrite(fp, &cliente, sizeof(cliente));
rfb = _Rreadn(fp, &cliente, sizeof(cliente), __DFT);
if (ind[F3] == IND_ON) {
return (F3);
} else if (ind[F12] == IND_ON) {
return (F12);
} else {
nombre
= CtoS(cliente.NOMBRE,
direccion = CtoS(cliente.DIRECCION,
localidad = CtoS(cliente.LOCALIDAD,
contacto = CtoS(cliente.CONTACTO,
telefono = ZtoD(cliente.TELEFONO,
email
= CtoS(cliente.EMAIL,
ingresos = ZtoD(cliente.INGRESOS,
fecha
= CtoS(cliente.FECHA,
hora
= CtoS(cliente.HORA,
return (F0);
}
sizeof(cliente.NOMBRE)
);
sizeof(cliente.DIRECCION) );
sizeof(cliente.LOCALIDAD) );
sizeof(cliente.CONTACTO)
);
sizeof(cliente.TELEFONO), 0);
sizeof(cliente.EMAIL)
);
sizeof(cliente.INGRESOS), 2);
sizeof(cliente.FECHA)
);
sizeof(cliente.HORA)
);
}
// Convierte string a cadecna de caracteres
void StoC(string str, char *car, int siz) {
Página 3
Documento: CLIENTEP.CPP
str.resize(siz);
str.copy(car,siz);
}
// Convierte cadena de caracteres a string
string CtoS(char *car, int siz) {
string str(car, siz);
return str;
}
// Convierte un Numero con Zona a decimal
_ConvertDecimal ZtoD(char *zon, int dig, int pre) {
// Creamos un string con la cadena del decimal con zona
string sdec(zon,dig);
int siz = sdec.length();
// Verificamos si el numero tiene signo
bool minus = false;
char last_char = sdec.at(siz-1);
// Si es asi, cambiamos el ultimo caracter s/especificaciones
if (last_char >= 0xD0 && last_char <= 0xD9) {
sdec.replace((siz-1),1,1,(last_char+0x20));
minus = true;
}
// A la cadena creada le anadimos el punto decimal si procede
if(pre>0) {
sdec.insert((siz-pre),".");
}
// Ponemos el signo
if(minus) {
sdec.insert(0,"-");
}
// Convertimos a decimal
return _ConvertDecimal((char *)sdec.c_str());
}
// Convierte un decimal a Numero con Zona
void DtoZ(_ConvertDecimal dec, char *zon) {
// Digitos del numero decimal
int dig = dec.DigitsOf();
// Precision del numero decimal
int pre = dec.PrecisionOf();
// Determinacion de la longitud del decimal convertido a cadena
int siz = dig;
// Si el decimal es negativo reservamos un espacio para el signo
if(dec < 0) siz++;
// Si el decimal tiene parte fraccionaria reservamos un espacio para el punto
if(pre > 0) siz++;
// Creamos un puntero para el decimal convertido a cadena
char * cdec = new char[siz+1];
// Obtenemos el decimal convertido a cadena
sprintf(cdec, "%0*.*D(*,*)", siz, pre, dig, pre, dec);
// Creamos un string con la cadena obtenida
string szon(cdec);
// Nos deshacemos del puntero, ya no lo necesitamos
delete [] cdec;
// Si es fraccionario eliminamos el punto decimal
if(pre > 0) {
szon.erase((siz-pre-1),1);
siz--;
}
// Si el decimal es negativo
if(dec < 0) {
// Sustituimos el utilo caracter s/especificaciones
char last_char = szon.at(siz-1);
szon.replace((siz-1),1,1,(last_char-0x20));
// Eliminamos el signo
szon.erase(0,1);
}
// Copiamos la cadena del string a zon
strncpy(zon,szon.c_str(),dig);
}
Página 1
Documento: CLIENTES.DSPF
A* CLIENTES.DSPF | Ejemplo pantalla con menu de edicion clientes
A
DSPSIZ(24 80 *DS3)
A
INDARA
A
HELP
A
CA03(03 'Salir')
A
CA12(12 'Cancelar')
A*------------------------------------------------------------------------A* Registros usados para la definicion de la ventana
A*------------------------------------------------------------------------A
R WDW01
A
WINDOW(5 11 13 55)
A
WDWBORDER((*COLOR WHT) (*DSPATR RI)A
(*CHAR '
'))
A
WDWTITLE((*TEXT 'Anadir cliente'))
A
1 1'Teclee elecciones, pulse Intro.'
A
COLOR(BLU)
A
2 1'Nombre cliente . . . .'
A
NOMBRE
30A B 2 26CHECK(LC)
A
3 1'Direccion . . . . . .'
A
DIRECCION
30A B 3 26CHECK(LC)
A
LOCALIDAD
30A B 4 26CHECK(LC)
A
5 1'Persona de contacto .'
A
CONTACTO
30A B 5 26CHECK(LC)
A
6 1'Telefono . . . . . . .'
A
TELEFONO
9Y 0B 6 26EDTCDE(4)
A
COMP(GE 0)
A
7 1'Correo electronico . .'
A
EMAIL
30A B 7 26CHECK(LC)
A
8 1'Cifra de negocios . .'
A
INGRESOS
15Y 2B 8 26EDTCDE(2)
A
COMP(GE .00)
A
9 1'Fecha de alta . . . .'
A
FECHA
L B 9 26DATFMT(*DMY)
A
DATSEP('/')
A
9 38'DD/MM/AA'
A
10 1'Hora de apertura . . .'
A
HORA
T B 10 26TIMFMT(*HMS)
A
TIMSEP(':')
A
10 38'HH:MM:SS'
A
11 51'Final'
A
DSPATR(HI)
A
12 1'F3=Salir F12=Cancelar'
A
COLOR(BLU)
A*------------------------------------------------------------------------A* Registro solo para remover la ventana de la pantalla antes de volver.
A*------------------------------------------------------------------------A
R RMVWDW
CLRL(*NO)
A
OVERLAY
A
FRCDTA
A*------------------------------------------------------------------------A* No es un registro de E/S, no se presenta y evita blanqueo de pantalla.
A*------------------------------------------------------------------------A
R DUMMY
ASSUME
A
1 11' '
A*------------------------------------------------------------------------A
R MENUBAR
A
MNUBAR
A
MNUBARDSP
A
MNUBARSW
A
MNUCNL
A
MNUFLD
2Y 0B 1 2MNUBARSEP((*DSPATR RI) (*CHAR ' ') +
A
(*COLOR GRN) )
A
MNUBARCHC(1 PULLFILE '>Archivo')
A
MNUBARCHC(2 PULLEDIT '>Edicion')
A
MNUBARCHC(3 PULLVIEW '>Vista')
A
MNUBARCHC(4 PULLOPT '>Opciones')
A
MNUBARCHC(5 PULLHELP 'A>yuda')
A*------------------------------------------------------------------------A
R PULLFILE
A
PULLDOWN(*SLTIND *RSTCSR)
Página 2
Documento: CLIENTES.DSPF
A
WDWBORDER((*COLOR GRN) (*DSPATR RI)A
(*CHAR '
'))
A
CA06(06 'Nuevo')
A
CA04(04 'Solicitud')
A
F1
2Y 0B 1 1SNGCHCFLD
A
CHOICE(1 '>Nuevo')
A
CHCACCEL(1 'F6')
A
CHOICE(2 '>Abrir...')
A
CHOICE(3 'E>xportar')
A
CHOICE(4 '>Enviar')
A
CHOICE(5 '>Imprimir...')
A
CHOICE(6 '>Salir')
A
CHCACCEL(6 'F3')
A*------------------------------------------------------------------------A
R PULLEDIT
A
PULLDOWN(*SLTIND *RSTCSR)
A
WDWBORDER((*COLOR GRN) (*DSPATR RI)A
(*CHAR '
'))
A
CA06(06 'Nuevo')
A
CA04(04 'Solicitud')
A
F1
2Y 0B 1 1SNGCHCFLD
A
CHOICE(1 '>Copiar')
A
CHOICE(2 '>Borrar')
A
CHOICE(3 'B>uscar')
A
CHCACCEL(3 'F4')
A*------------------------------------------------------------------------A
R PULLVIEW
A
PULLDOWN(*SLTIND *RSTCSR)
A
WDWBORDER((*COLOR GRN) (*DSPATR RI)A
(*CHAR '
'))
A
CA06(06 'Nuevo')
A
CA04(04 'Solicitud')
A
F1
2Y 0B 1 1SNGCHCFLD
A
CHOICE(1 '>Ordenar...')
A
CHOICE(2 '>Filtrar...')
A
CHOICE(3 '>Totalizar...')
A*------------------------------------------------------------------------A
R PULLOPT
A
PULLDOWN(*SLTIND *RSTCSR)
A
WDWBORDER((*COLOR GRN) (*DSPATR RI)A
(*CHAR '
'))
A
CA06(06 'Nuevo')
A
CA04(04 'Solicitud')
A
F1
2Y 0B 1 1SNGCHCFLD
A
CHOICE(1 '>Preferencias')
A*------------------------------------------------------------------------A
R PULLHELP
A
PULLDOWN(*SLTIND *RSTCSR)
A
WDWBORDER((*COLOR GRN) (*DSPATR RI)A
(*CHAR '
'))
A
CA06(06 'Nuevo')
A
CA04(04 'Solicitud')
A
F1
2Y 0B 1 1SNGCHCFLD
A
CHOICE(1 '>Ver la ayuda')
A
CHOICE(2 '>Acerca de ...')
A*------------------------------------------------------------------------A
R APPSCR
A
CA06(06 'Nuevo')
A
CA04(04 'Solicitud')
A
MNUBARDSP(MENUBAR &MNUCHOICE &PULLIA
NPUT)
A
MNUCHOICE
2Y 0H
A
PULLINPUT
2S 0H
A
12 23'F i c h a s
d e
c l i e n t e A
s'
A
COLOR(RED)
A
23 2'F3=Salir F6=Anadir F4=Solicitud +
A
F12=Cancelar'
A
COLOR(BLU)
Página 1
Documento: CRTMNMWND.C
/*
* CRTMNMWND.C | Ejemplo de creacion y manipulacion de ventanas
* ILE C/C++ (System i)
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "qsnapi.h"
void GenericDraw(const Qsn_Cmd_Buf_T *cbuf, const Qsn_Win_T *win) {
char *msg1 = "F3: Cerrar F4: Mover F5: Tamano";
char *msg2 = "Texto sin atributos";
QsnWrtDta(msg2, strlen(msg2), 0, 2, 1, QSN_NO_SA, QSN_NO_SA,
QSN_NO_SA, QSN_NO_SA, *cbuf, *win, NULL);
QsnWrtDta(msg1, strlen(msg1), 0, -1, 1, QSN_SA_HI, QSN_SA_NORM,
QSN_SA_RED, QSN_SA_NORM, *cbuf, *win, NULL);
}
void Draw1(const Qsn_Win_T *win, const Qsn_Cmd_Buf_T *cbuf) {
char *txt = "Ventana 1 (UL/Azul)";
GenericDraw(cbuf, win);
QsnWrtDta(txt, strlen(txt), 0, 5, 5, QSN_SA_UL, QSN_SA_NORM,
QSN_SA_BLU, QSN_SA_NORM, *cbuf, *win, NULL);
}
void Draw2(const Qsn_Win_T *win, const Qsn_Cmd_Buf_T *cbuf) {
char *txt = "Ventana 2 (UL/Rojo)";
GenericDraw(cbuf, win);
QsnWrtDta(txt, strlen(txt), 0, 5, 5, QSN_SA_UL, QSN_SA_NORM,
QSN_SA_RED, QSN_SA_NORM, *cbuf, *win, NULL);
}
void Draw3(const Qsn_Win_T *win, const Qsn_Cmd_Buf_T *cbuf) {
char *txt = "Ventana 3 (UL/Rosa)";
GenericDraw(cbuf, win);
QsnWrtDta(txt, strlen(txt), 0, 5, 5, QSN_SA_UL, QSN_SA_NORM,
QSN_SA_PNK, QSN_SA_NORM, *cbuf, *win, NULL);
}
int main (void) {
int i;
char text[100];
Qsn_Win_T win1, win2, win3, cur;
Qsn_Win_Desc_T win_desc;
Qsn_Win_Ext_Inf_T ext = { NULL, NULL, NULL, NULL, NULL, NULL };
Q_Bin4 win_desc_length = sizeof(win_desc);
char aid;
QsnInzWinD(&win_desc, win_desc_length, NULL);
win_desc.GUI_support = '0';
/* definir y arrancar la ventana 1 */
win_desc.top_row = 3;
win_desc.left_col = 5;
win_desc.num_rows = 13;
win_desc.num_cols = 40;
ext.draw_fp = Draw1;
win1 = QsnCrtWin(&win_desc, win_desc_length, &ext, sizeof(ext),
'1', NULL, 0, NULL, NULL);
QsnGetAID(NULL, 0, NULL);
/* definir y arrancar la ventana 2 */
win_desc.top_row = 10;
win_desc.left_col = 10;
win_desc.num_rows = 10;
win_desc.num_cols = 30;
ext.draw_fp = Draw2;
win2 = QsnCrtWin(&win_desc, win_desc_length, &ext, sizeof(ext),
'1', NULL, 0, NULL, NULL);
QsnGetAID(NULL, 0, NULL);
Página 2
}
Documento: CRTMNMWND.C
/* definir y arrancar la ventana 3 */
win_desc.top_row = 5;
win_desc.left_col = 20;
win_desc.num_rows = 15;
win_desc.num_cols = 50;
ext.draw_fp = Draw3;
win3 = QsnCrtWin(&win_desc, win_desc_length, &ext, sizeof(ext),
'1', NULL, 0, NULL, NULL);
cur = win3;
for ( ;; ) {
if (( (aid=QsnGetAID(NULL, 0, NULL)) == QSN_F3))
break;
else if (aid == QSN_F4)
QsnMovWinUsr(cur, NULL);
else if (aid == QSN_F5)
QsnRszWinUsr(cur, NULL);
else {
/* cambiar de la ventana actual a la ventana siguiente */
if (cur == win1) {
QsnSetCurWin(win2, NULL);
cur = win2;
} else if (cur == win2) {
QsnSetCurWin(win3, NULL);
cur = win3;
} else {
QsnSetCurWin(win1, NULL);
cur = win1;
}
}
}
Página 1
Documento: CTRCOMMITC.CLLE
/* CTRCOMMITC.CLLE | Ejemplo de uso del control de compromiso */
PGM
/* Crear receptor de diario */
CRTJRNRCV JRNRCV(*CURLIB/TMPRECEIVE)
/* Crear diario y adjuntarlo al receptor de diario */
CRTJRN
JRN(*CURLIB/TMPJOURNAL) JRNRCV(TMPRECEIVE)
/* Dirigir las entradas de diario del archivo(s) al diario */
STRJRNPF
FILE(USUARIOSF) JRN(TMPJOURNAL)
/* Iniciar el control de compromiso con el nivel de bloqueo mas alto */
STRCMTCTL LCKLVL(*ALL) CMTSCOPE(*JOB)
/* Llamar al programa */
CALL
PGM(CTRCOMMITP)
/* Finaliza control compromiso y provoca la ejecucion de una operacion de retrotraccion implicita *
/
ENDCMTCTL
/* Fin reg por diario arch fisico */
ENDJRNPF
FILE(USUARIOSF) JRN(TMPJOURNAL)
/* Suprimir diario */
DLTJRN
JRN(TMPJOURNAL)
/* Suprimir receptor de diario */
DLTJRNRCV JRNRCV(TMPRECEIVE) DLTOPT(*IGNINQMSG)
ENDPGM
Página 1
Documento: CTRCOMMITP.CPP
// CTRCOMMITP.CPP | Ejemplo de uso del control de compromiso
// ILE C/C++ (System i)
// Funciones: _Rcommit, _Rindara, _Rclose, _Rformat, _Ropen, _Rreadn, _Rrollbck, _Rwrite
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<string.h>
<recio.h>
#define PANTALLA "*LIBL/CTRCOMMITS"
#define ARCHIVO "*LIBL/USUARIOSF"
typedef _Packed struct {
char NOMBRE[30];
char DIRECCION[40];
char TELEFONO[10];
} PANTALLA_REGISTRO;
typedef _Packed struct {
char USUARIO[10];
char CLAVE[10];
char NOMBRE[30];
char DIRECCION[40];
char TELEFONO[10];
short int EDAD;
int CUOTA;
} ARCHIVO_ENTRADA;
#define PF03 2
#define IND_OFF '0'
#define IND_ON '1'
int main(void) {
int rc = 1;
_RFILE *dspfile;
_RFILE *pfile;
_SYSindara ind_area;
PANTALLA_REGISTRO dspreg;
ARCHIVO_ENTRADA preg;
/* Apertura de archivo de pantalla y el de la transaccion */
if ((dspfile = _Ropen(PANTALLA, "ar+,indicators=y")) == NULL) {
printf("No se abrio el archivo de la pantalla.\n");
exit(1);
}
if ((pfile = _Ropen(ARCHIVO, "ar,commit=y")) == NULL) {
printf("No se abrio el archivo de la transaccion.\n");
exit(2);
}
/* Asociar area de indicadores separada para el archivo */
_Rindara(dspfile, ind_area);
/* Seleccion del formato de registro */
_Rformat(dspfile, "REGISTRO");
/* Mientras el usuario introduzca transacciones, actualizar archivo. */
do {
/* Invitar a usuario para insertar una transaccion. */
/* La funcion _Rwrite escribe la pantalla. */
_Rwrite(dspfile, "", 0);
_Rreadn(dspfile, &dspreg, sizeof(dspreg), __DFT);
/* Copiamos datos pantalla a fichero */
strncpy(preg.USUARIO , dspreg.NOMBRE
, 10);
strncpy(preg.CLAVE
, "
"
, 10);
strncpy(preg.NOMBRE
, dspreg.NOMBRE
, 30);
Página 2
}
Documento: CTRCOMMITP.CPP
strncpy(preg.DIRECCION, dspreg.DIRECCION, 40);
strncpy(preg.TELEFONO , dspreg.TELEFONO , 10);
preg.EDAD = 0;
preg.CUOTA = 0;
if (ind_area[PF03] == IND_OFF) {
/* Actualizacion del archivo de transacciones */
rc = ((_Rwrite(pfile, &preg, sizeof(preg)))->num_bytes);
/* Si se actualizaron las bases de datos, a continuacion, confirmar la transaccion */
/* De lo contrario reversion de la transaccion e indicar el error */
/* de la aplicacion al usuario. */
if (rc) {
_Rcommit("Transaccion completa");
} else {
_Rrollbck();
_Rformat(dspfile, "ERROR");
_Rwrite(dspfile, "", 0);
_Rreadn(dspfile, "", 0, __DFT);
}
}
} while (ind_area[PF03] == IND_OFF && rc);
_Rclose(dspfile);
_Rclose(pfile);
Página 1
Documento: CTRCOMMITS.DSPF
A* CTRCOMMITS.DSPF | Ejemplo de
A
A
A
R REGISTRO
A
A
A
A
A
NOMBRE
30A
A
A
DIRECCION
40A
A
A
TELEFONO
10A
A
A
A
R ERROR
A
A
A
A
uso del control de compromiso
DSPSIZ(24 80 *DS3)
INDARA
CF03(03 'Salir')
1 27'Lista de telefonos'
DSPATR(HI)
7 19'Nombre:'
I 7 27
9 16'Direccion:'
I 9 27
11 17'Telefono:'
I 11 27
23 27'F3=Salir'
COLOR(BLU)
CF03(03 'Salir')
12 21'¡No se ha podido realizar la operacion!'
COLOR(RED)
Página 1
Documento: SUBFILEP.CPP
// SUBFILEP.CPP | Ejemplo de uso de subficheros
// ILE C/C++ (System i)
/*
* Escritura de subfichero y visualizacion del formato de registro de control
* Funciones: _Rwrited, _Rclose, _Rformat, _Ropen, _Rreadn, _Rreadnc, _Rwrite
*/
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<recio.h>
<string.h>
#define DSPFILENAME "*LIBL/SUBFILES"
#define PFILENAME "*LIBL/USUARIOSF"
#define NUM_REGS 1000
#define IND_ON '1'
#define SFL_END 98
typedef struct {
char usuario[10];
char clave[10];
char nombre[30];
char direccion[40];
char telefono[10];
short edad;
short cuota;
} pf_t;
#define REGLEN_PF sizeof(pf_t)
typedef struct {
char usuario[10];
char telefono[10];
} dspf_t;
#define REGLEN_DSPF sizeof(dspf_t)
void init_subfile(_RFILE *, _RFILE *);
int main (void) {
_RFILE * pf;
_RFILE * subf;
/* Apertura del subfichero y del archivo fisico. */
if ((pf = _Ropen(PFILENAME, "rr")) == NULL) {
printf("No se puede abrir el archivo %s\n", PFILENAME);
exit(1);
}
if ((subf = _Ropen(DSPFILENAME, "ar+ indicators=y")) == NULL) {
printf("No se puede abrir el archivo %s\n", DSPFILENAME);
exit(2);
}
/* inicializar el subfichero con los registros del archivo fisico */
init_subfile(pf, subf);
/* Se muestra de la pantalla, el formato de registro de control del subfichero */
_Rformat(subf, "SFLCTL");
_Rwrite(subf, "", 0);
_Rreadnc(subf, "", 0); // Leer siguiente registro cambiado en subfichero
// _Rreadn(subf, "", 0, __DFT); // Leer siguiente registro
/* Cerrar el archivo fisico y el subfichero */
_Rclose(pf);
_Rclose(subf);
}
void init_subfile(_RFILE * pf, _RFILE * subf) {
_RIOFB_T *fb;
Página 2
}
Documento: SUBFILEP.CPP
_SYSindara area_indicador;
_Rindara(subf, area_indicador);
pf_t reg_pf;
dspf_t reg_dspf;
int i;
/* Seleccionar el formato de registro del subfichero */
_Rformat(subf, "SFL");
for(i = 1; i <= NUM_REGS; i ++) {
fb = _Rreadn(pf, &reg_pf, REGLEN_PF, __DFT);
if (fb->num_bytes != EOF) {
if (fb->num_bytes != REGLEN_PF) {
printf("Ha ocurrido un error en la lectura\n");
printf("Bytes leidos: %d\n", fb->num_bytes);
printf("Bytes esperados: %d\n", REGLEN_PF);
exit(3);
}
strcpy(reg_dspf.usuario, reg_pf.usuario);
strcpy(reg_dspf.telefono, reg_pf.telefono);
fb = _Rwrited(subf, &reg_dspf, REGLEN_DSPF, i);
if (fb-> num_bytes != REGLEN_DSPF) {
printf("Ha ocurrido un error en la escritura\n");
exit(4);
}
} else {
area_indicador[SFL_END] = IND_ON;
break;
}
}
Página 1
Documento: SUBFILES.DSPF
A* SUBFILES.DSPF | Ejemplo de uso
A
A
A
A
R SFL
A
USUARIO
10A O
A
TELEFONO
10A O
A
R SFLCTL
A
A
A
A
A 99
A
A
A
A
de subficheros
DSPSIZ(24 80 *DS3)
INDARA
CA03(03 'Salir')
SFL
10 29
10 42
SFLCTL(SFL)
SFLSIZ(0010)
SFLPAG(0005)
SFLDSP
SFLDSPCTL
SFLEND(*PLUS)
22 29'<AvPag> Pag.Siguiente'
COLOR(BLU)
23 29'<RePag> Pag.Anterior'
COLOR(BLU)
IBM System I ILE C/C++
La plantilla de clase _DecimalT
Cuando se trabaja con ILE C++, la plantilla de clase _DecimalT
permite la representación de hasta 31 dígitos significativos,
incluyendo la parte entera y fraccionaria. La parte fraccionaria de un
euro se puede representar con una precisión de dos dígitos después del
punto decimal.
Nota: No se tiene por qué utilizar la aritmética de punto flotante. El
punto flotante es más adecuado en los cálculos científicos y de
ingeniería, que utilizan números en los que a menudo:
-
La
se
La
se
el
variable es mucho mayor que el mayor decimal empaquetado que
puede almacenar.
variable es mucho menor que el menor decimal empaquetado que
puede almacenar, pero no tienen la suficiente precisión para
uso comercial.
Las mismas declaraciones y los operadores que se utilizan en otros
tipos de datos, como el flotante, se pueden aplicar a la plantilla de
clase _DecimalT, con la excepción de las uniones y de los operadores
de bits, que no se aplican a plantilla de clase _DecimalT.
Usted puede:
-
-
-
Declarar definición de tipos, matrices y estructuras que
contengan la plantilla de clase _DecimalT.
Aplicar operadores aritméticos, relacionales, asignación, coma,
igualdad, condicional, lógico y unarios a la plantilla de clase
_DecimalT.
Pasar la plantilla de clase _DecimalT en las llamadas a
funciones. La plantilla de clase _DecimalT es compatible con las
representaciones de decimales empaquetados de lenguajes ILE.
Definir macros y llamar a la biblioteca de funciones de
plantilla de clase _DecimalT.
Ver la plantilla de clase _DecimalT cuando se utiliza el
depurador ILE del sistema.
Página 1
Documento: WRITINGDEC.CPP
// WRITINGDEC.CPP | Ejemplo operaciones archivo con valores _DecimalT
// ILE C/C++ (System i)
// Este programa muestra como escribir constantes de plantilla de clase _DecimalT
// en un archivo y volver a recuperarlas de nuevo.
// Muestra como pasar una matriz de plantilla de clase _DecimalT a una funcion.
#include <stdlib.h>
#include <iostream.h>
#include <bcd.h>
// Declaracion del tamano de la matriz decimal
#define N 3
// Declaracion de matrices validas
_DecimalT<4, 2> arr_1[] = { __D("12.34"), __D("-34.56"), __D("78.90") };
_DecimalT<4, 2> arr_2[N];
// Declarar funcion de escritura en un archivo
void write_num(_DecimalT<4, 2> a[N]);
// Declarar funcion para leer de un archivo
void read_num(_DecimalT<4, 2> b[N]);
// Declaracion del puntero al archivo
FILE *stream;
int main(void) {
// Abrir archivo. Se debe usar fopen() para tener acceso a un archivo fisico
if ((stream = fopen("WRITINGDEC.DAT", "w+")) == NULL) {
cout << "No se puede abrir el archivo";
exit(EXIT_FAILURE);
}
// Llama a funcion para escribir los valores de la matriz mediante la funcion fprintf()
write_num(arr_1);
// Colocar el puntero del archivo
int reposition = fseek(stream, 0L, SEEK_SET);
if (reposition != 0) {
cout << "fseek() no pudo colocar el puntero del archivo" << endl;
exit(EXIT_FAILURE);
}
// Llama a funcion para leer los valores de la matriz del archivo mediante la funcion fscanf()
read_num(arr_2);
// Cierre del archivo
fclose(stream);
}
// A write_num se le pasa una matriz.
// Estos valores se escriben en un archivo de texto con fprintf()
// Si la funcion tiene exito se devuelve un 0, en caso contrario
// se devuelve un valor negativo (que indica un error).
void write_num(_DecimalT<4, 2> a[N]) {
int i, j;
for (i = 0; i < N; i++) {
j = fprintf(stream, "%D(4,2)\n", a[i]);
if (j < 0)
cout << "Numero no escrito en el archivo " << a[i] << endl;
else
cout << "Numero escrito en el archivo " << a[i] << endl;
}
}
// A read_num se le pasa una matriz.
// Los valores se leen de un archivo de texto con fscanf().
// Si la funcion tiene exito se devuelve un 0, en caso contrario
// se devuelve un valor negativo (que indica un error).
void read_num(_DecimalT<4, 2> b[N]) {
int i, j;
for (i = 0; i < sizeof(b) / sizeof(b[0]); i++) {
j = fscanf(stream, "%D(4,2)\n", &b[i]);
Página 2
}
Documento: WRITINGDEC.CPP
if (j < 0)
cout << "Error al leer del archivo" << endl;
}
for (i = 0; i < N; i++) cout << "b[" << i << "]=" << b[i] << endl;
Página 1
Documento: USUARIOSF.PF
* ------------------------------------------------------* ARCHIVO FISICO: USUARIOSF.PF | Ejemplo de tabla de usuarios
* ------------------------------------------------------A
UNIQUE
A
R ENTRADA
A
USUARIO
10A
A
CLAVE
10A
A
NOMBRE
30A
A
DIRECCION
40A
A
TELEFONO
10A
A
EDAD
3B
A
CUOTA
6B
A
K USUARIO
/*
* USUARIOSD.SQL | Datos test USUARIOSF.PF-Ejemplo tabla usuarios
*/
INSERT INTO USUARIOSF VALUES
('USUARIO01', 'CLAVE01', 'NOMBRE01', 'DIRECCION01', 'TELEFONO01',
('USUARIO02', 'CLAVE02', 'NOMBRE02', 'DIRECCION02', 'TELEFONO02',
('USUARIO03', 'CLAVE03', 'NOMBRE03', 'DIRECCION03', 'TELEFONO03',
('USUARIO04', 'CLAVE04', 'NOMBRE04', 'DIRECCION04', 'TELEFONO04',
('USUARIO05', 'CLAVE05', 'NOMBRE05', 'DIRECCION05', 'TELEFONO05',
('USUARIO06', 'CLAVE06', 'NOMBRE06', 'DIRECCION06', 'TELEFONO06',
('USUARIO07', 'CLAVE07', 'NOMBRE07', 'DIRECCION07', 'TELEFONO07',
('USUARIO08', 'CLAVE08', 'NOMBRE08', 'DIRECCION08', 'TELEFONO08',
('USUARIO09', 'CLAVE09', 'NOMBRE09', 'DIRECCION09', 'TELEFONO09',
('USUARIO10', 'CLAVE10', 'NOMBRE10', 'DIRECCION10', 'TELEFONO10',
('USUARIO11', 'CLAVE11', 'NOMBRE11', 'DIRECCION11', 'TELEFONO11',
('USUARIO12', 'CLAVE12', 'NOMBRE12', 'DIRECCION12', 'TELEFONO12',
('USUARIO13', 'CLAVE13', 'NOMBRE13', 'DIRECCION13', 'TELEFONO13',
('USUARIO14', 'CLAVE14', 'NOMBRE14', 'DIRECCION14', 'TELEFONO14',
('USUARIO15', 'CLAVE15', 'NOMBRE15', 'DIRECCION15', 'TELEFONO15',
('USUARIO16', 'CLAVE16', 'NOMBRE16', 'DIRECCION16', 'TELEFONO16',
('USUARIO17', 'CLAVE17', 'NOMBRE17', 'DIRECCION17', 'TELEFONO17',
('USUARIO18', 'CLAVE18', 'NOMBRE18', 'DIRECCION18', 'TELEFONO18',
('USUARIO19', 'CLAVE19', 'NOMBRE19', 'DIRECCION19', 'TELEFONO19',
('USUARIO20', 'CLAVE20', 'NOMBRE20', 'DIRECCION20', 'TELEFONO20',
001,
002,
003,
004,
005,
006,
007,
008,
009,
010,
011,
012,
013,
014,
015,
016,
017,
018,
019,
020,
000100),
000200),
000300),
000400),
000500),
000600),
000700),
000800),
000900),
001000),
001100),
001200),
001300),
001400),
001500),
001600),
001700),
001800),
001900),
002000)

Documentos relacionados