Introducción al lenguaje C. Solución ejercicios

Elementos de un programa C. Tipos básicos de datos. E/S básica. Sentencias de control. Funciones. Asignación dinámica de memoria. Ficheros. Ficheros indexados: la interfase Btrieve. Compilación y enlazado. Biblioteca de funciones de Turbo C

  • Enviado por: Juan
  • Idioma: castellano
  • País: España España
  • 58 páginas
publicidad

14

Soluciones a los

ejercicios

1. Introducción

/* Capítulo 1. Ejercicio 1 */

LÍNEA

PONE

DEBE PONER

1

include studio.h

#include <stdio.h>

2

... semana /*

... semana */

3

main {}

main ()

4

(

{

5

int d

int d;

6

d := 7;

d = 7;

7

print (Hay d días en una semana);

printf ("Hay %d días en una semana", d);

8

}

/* Capítulo 1. Ejercicio 2 */

a) Historias de cronopios y famas.Autor: Julio Cortázar

b) ¿Cuántas líneas

ocupa esto?

c) Estamos

aprendiendo /naprogramar en C

d) 2 + 2 = 4

/* Capítulo 1. Ejercicio 3 */

#include <stdio.h>

main ()

{

int R;

float S, L;

printf ("\nCálculo del área de un círculo y longitud de su circunferencia");

printf ("\nRadio: ");

scanf ("%d", &R);

S = 3.14 * R * R;

L = 2 * 3.14 * R;

printf ("\nAREA: %f", S);

printf ("\nCIRCUNFERENCIA: %f", L);

}

/* Capítulo 1. Ejercicio 4 */

#include <stdio.h>

main ()

{

int L1, L2, S1, S2, S;

printf ("\nLongitud del cuadrado mayor: ");

scanf ("%d", &L1);

printf ("\nLongitud del cuadrado menor: ");

scanf ("%d", &L2);

S1 = AreaCuadrado (L1);

S2 = AreaCuadrado (L2);

S = S1 - S2;

printf ("\nSolución: %d", S);

}

AreaCuadrado (int x)

{

return x * x;

}

2. Elementos de un programa C

/* Capítulo 2. Ejercicio 1 */

Como carácter de escape '\n'

Código ASCII en octal '\012'

Código ASCII en hex '\xA'

/* Capítulo 2. Ejercicio 2 */

a) Es una constante entera decimal: 12

b) Es una constante entera octal: 012 (10 decimal)

c) Es una constante entera hexadecimal: 0x12 (18 decimal)

d) Es una constante entera hexadecimal: 0X12 (18 decimal)

e) Es el carácter N

f) Es el carácter de código ASCII hexadecimal 12 (18 decimal)

g) Es el carácter de código ASCII hexadecimal 1B (27 decimal): ESCAPE

h) Es el carácter de código octal 34 (28 decimal)

/* Capítulo 2. Ejercicio 3 */

f) 2dias comienza por un número

h) Suma-Total no se permite el guión -

/* Capítulo 2. Ejercicio 4 */

x

y

z

u

v

t

valores iniciales

2

3

4

5

6

7

x++;

3

y = ++z;

5

5

t = --v;

5

5

v = x + (y += 3) / 2;

15

10

u = x + y / 2;

10

/* Capítulo 2. Ejercicio 5 */

El carácter '\a' es el carácter de escape correspondiente al ASCII 7 (beep), mientras que el carácter '\A' es lo mismo que 'A'.

La diferencia entre 'A' y "A" estriba en que el primero es un carácter simple (comillas simples) mientras que el segundo es una cadena de caracteres (comillas dobles) y, por tanto, consta de dos caracteres: el carácter 'A' y el carácter nulo.

/* Capítulo 2. Ejercicio 6 */

a) x > y && z > t * V && z > t * V && V * V

b) x < y && z > t * F && z > t * F && V * F

c) x < y || z > t * F || z > t * F || V * V

d) !0 * !F * V

e) !1 * !V * F

f) 0 != 1 * V

g) 0 != !1 * F != !V * F != F * F

h) 0 == !1 * F == !V * F == F * V

i) 200 || x * V || V * V

j) x * 0 * 0 * F

k) x * y * 200 * V

l) !!0 * !!F * !V * F

m) !(0 == 0) * !V * F

n) 10 > 5 && !(10 < 9) || 3 <= 4 * 10 > 5 && !F || 3 <= 4 *

* 10 > 5 && V || 3 <= 4 * V && V || 3 <= 4 * V && V || V *

* V || V * V

ñ) 1 && !0 || 1 * V && !F || V * V && V || V * V || V * V

o) 1 && !(0 || 1) * V && !(F || V) * V && !V * V && F * F

/* Capítulo 2. Ejercicio 7 */

Si x = 10

Si x = 8

y = (x > 9 ? ++x : --x);

y = 11, x = 11

y = 7, x = 7

y = (x > 9 ? x++: x--);

y = 10, x = 11

y = 8, x = 7

/* Capítulo 2. Ejercicio 8 */

#include <stdio.h>

main ()

{

int C;

float F;

printf ("\nGrados centígrados: ");

scanf ("%d", &C);

F = ((float) 9 / 5) * C + 32;

printf ("\n%d grados Centígrados equivalen a %f grados Fahrenheit", C, F);

}

/* Capítulo 2. Ejercicio 9 */

#include <stdio.h>

main ()

{

unsigned int nhex, alto, bajo;

printf ("\nTeclee un número hexadecimal: ");

scanf ("%x", &nhex);

bajo = (nhex & 0x00FF) << 8;

alto = (nhex & 0xFF00) >> 8;

nhex = alto | bajo;

printf ("\nResultado: %x", nhex);

}

/* Capítulo 2. Ejercicio 10 */

#include <stdio.h>

main ()

{

unsigned int nhex;

printf ("\nTeclee un número hex: ");

scanf ("%x", &nhex);

nhex &= 0xFDB6; // máscara = 1111 1101 1011 0110

nhex |= 0x0924; // máscara = 0000 1001 0010 0100

nhex ^= 0xF492; // máscara = 1111 0100 1001 0010

printf ("\nResultado: %x", nhex);

}

/* Capítulo 2. Ejercicio 11 */

#include <stdio.h>

main ()

{

int num1, num2, dif;

printf ("\nTeclee 2 números enteros: ");

scanf ("%d %d", &num1, &num2);

dif = (num1 > num2 ? num1 - num2 : num2 - num1);

dif *= 3;

printf ("\nResultado: %d", dif);

}

/* Capítulo 2. Ejercicio 12 */

#include <stdio.h>

main ()

{

int num, cociente, resto, solucion;

printf ("\nTeclee un número entero de 4 cifras: ");

scanf ("%d", &num);

cociente = num / 100;

resto = num % 100;

solucion = (resto >= 50 ? cociente + 1 : cociente);

solucion *= 100;

printf ("\nResultado: %d", solucion);

}

3. Tipos básicos de datos

/* Capítulo 3. Ejercicio 1 */

a) unsigned long int

b) unsigned char

c) float

d) char

e) float

f) unsigned int

g) unsigned char

h) float

i) float

/* Capítulo 3. Ejercicio 2 */

Se admite por teclado un carácter (sentencia scan). Si el código ASCII de este carácter es mayor que 127 (es decir, si es un carácter del conjunto ASCII extendido) se incrementa su código en 1. En caso contrario se decrementa en 1. Por tanto, si se teclea un carácter del conjunto ASCII extendido, se visualiza el siguiente de la tabla; en caso contrario se visualiza el anterior.

/* Capítulo 3. Ejercicio 3 */

ÁMBITO

TIEMPO DE VIDA

a

Todo el programa, pues es una variable global.

Durante todo el programa.

b

La función main() pues es local a ella.

Mientras se ejecuta main().

c

La función MiFuncion(), pues es local a ella.

Mientras se ejecuta MiFuncion().

d

La función MiFuncion(), pues es local a ella.

Durante todo el programa, pues es una variable estática.

4. E/S básica

/* Capítulo 4. Ejercicio 1 */

#include <stdio.h>

#define CLS printf ("\033[2J") // Borra pantalla

main ()

{

unsigned char caracter;

CLS;

printf ("\033[7m"); // Vídeo inverso

printf ("Teclee un código ASCII (0-255): ");

scanf ("%d", &caracter);

printf ("\033[5;1;37;41m"); // Blanco intenso parpadeante sobre rojo

printf ("\nEl carácter correspondientes es %c", caracter);

printf ("\033[0m"); // Atributos normales

}

/* Capítulo 4. Ejercicio 2 */

#include <stdio.h>

#include <conio.h>

main ()

{

unsigned int caracter;

clrscr ();

textcolor (YELLOW);

textbackground (BLUE);

cprintf ("Teclee un carácter: ");

caracter = getche ();

textcolor (WHITE);

textbackground (RED);

cprintf ("\n\rCODIGO ASCII Decimal ........... %u", caracter);

cprintf ("\n\r Octal ............... %o", caracter);

cprintf ("\n\r Hexadecimal ... %X", caracter);

textattr (LIGHTGRAY | BLACK * 16);

}

/* Capítulo 4. Ejercicio 3 */

#include <stdio.h>

#include <conio.h>

main ()

{

float n1, n2;

textattr (YELLOW | BLUE * 16);

clrscr ();

cprintf ("\n\rA continuación debe teclear dos números de tipo float");

cprintf ("\n\rLa parte entera no debe tener más de 3 dígitos");

cprintf ("\n\rLa parte decimal se redondeará a 2 dígitos");

cprintf ("\n\r==> ");

cscanf ("%f %f", &n1, &n2);

textcolor (YELLOW);

textbackground (RED);

gotoxy (35, 10); cprintf ("%6.2f", n1);

gotoxy (35, 11); cprintf ("%6.2f", n2);

gotoxy (35, 12); cprintf ("------");

gotoxy (35, 13); cprintf ("%6.2f", n1 + n2);

textcolor (LIGHTGRAY);

textbackground (BLACK);

}

/* Capítulo 4. Ejercicio 4 */

#include <stdio.h>

#include <conio.h>

main ()

{

int n1, n2, unidad, decena, centena, resto;

textattr (YELLOW | BLUE * 16);

clrscr ();

cprintf ("\n\rTeclee dos números enteros de 3 dígitos: ");

cscanf ("%d %d", &n1, &n2);

centena = n2 / 100;

resto = n2 % 100;

decena = resto / 10;

unidad = resto % 10;

cprintf ("\n\r%6d", n1);

cprintf ("\n\r x %3d", n2);

cprintf ("\n\r------");

cprintf ("\n\r%6d", n1 * unidad);

cprintf ("\n\r%5d", n1 * decena);

cprintf ("\n\r%4d", n1 * centena);

cprintf ("\n\r------");

cprintf ("\n\r%6ld", (long) n1 * n2);

textattr (LIGHTGRAY | BLACK * 16);

}

/* Capítulo 4. Ejercicio 5 */

#include <stdio.h>

#include <conio.h>

main ()

{

int anyo, A, B, C, D, E, N, mes, dia;

printf ("\033[2J"); // Borra pantalla

printf ("\033[12;36H"); // Cursor a fila 12, columna 36

printf ("Año: ");

scanf ("%d", &anyo);

A = anyo % 19;

B = anyo % 4;

C = anyo % 7;

D = (19 * A + 24) % 30;

E = (2 * B + 4 * C + 6 * D + 5) % 7;

N = 22 + D + E;

mes = (N > 31 ? 4 : 3);

dia = (mes == 3 ? N : N - 31);

printf ("\033[1;5m"); // Alta intensidad y parpadeo

printf ("\033[14;19H"); // Cursor a fila 14, columna 19

printf ("Primer Domingo de Pascua: %02d/%02d/%02d", dia, mes, anyo % 100);

printf ("\033[0m"); // Desactiva atributos

}

/* Capítulo 4. Ejercicio 6 */

#include <stdio.h>

#include <conio.h>

#define LF fprintf (stdprn, "\n\r");

#define FF fprintf (stdprn, "\f");

main ()

{

char nombre1[21], nombre2[21];

int edad1, edad2;

float altura1, peso1, altura2, peso2;

float edad_m, altura_m, peso_m;

clrscr ();

textcolor (WHITE);

textbackground (BLUE);

Presentar ();

gotoxy (14, 3); gets (nombre1);

gotoxy (14, 4); scanf ("%d", &edad1);

gotoxy (14, 5); scanf ("%f", &altura1);

gotoxy (14, 6); scanf ("%f", &peso1);

getchar ();

textcolor (BLUE);

textbackground (WHITE);

Presentar ();

gotoxy (14, 9); gets (nombre2);

gotoxy (14, 10); scanf ("%d", &edad2);

gotoxy (14,11); scanf ("%f", &altura2);

gotoxy (14, 12); scanf ("%f", &peso2);

getchar ();

edad_m = (float) (edad1 + edad2) / 2;

altura_m = (altura1 + altura2) / 2;

peso_m = (peso1 + peso2) / 2;

LF; fprintf (stdprn, "NOMBRE EDAD ALTURA PESO");

LF; fprintf (stdprn, "=======================================");

LF; fprintf (stdprn, "%-20s %2d %4.1f %6.2f", nombre1, edad1, altura1, peso1);

LF; fprintf (stdprn, "%-20s %2d %4.1f %6.2f", nombre2, edad2, altura2, peso2);

LF;

LF; fprintf (stdprn, "%20s %5.2f %5.2f %6.2f", "Media:", edad_m, altura_m, peso_m);

FF;

textcolor (LIGHTGRAY);

textbackground (BLACK);

}

Presentar ()

{

cprintf ("\n\rINTRODUZCA LOS SIGUIENTES DATOS:");

cprintf ("\n\rNombre ..... ");

cprintf ("\n\rEdad .......... ");

cprintf ("\n\rAltura ........ ");

cprintf ("\n\rPeso .......... ");

}

5. Sentencias de control

/* Capítulo 5. Ejercicio 1 */

#include <stdio.h>

#include <conio.h>

main ()

{

float nota;

clrscr ();

do {

printf ("Nota: ");

scanf ("%f", &nota);

} while (nota < 0 || nota > 10);

if (nota >= 8.5) {

textattr (YELLOW | BLUE * 16);

cprintf ("SOBRESALIENTE"); }

else if (nota >= 7) {

textattr (BLACK | GREEN * 16);

cprintf ("NOTABLE"); }

else if (nota >= 6) {

textattr (BLACK | GREEN * 16);

cprintf ("BIEN"); }

else if (nota >= 5) {

textattr (BLACK | GREEN * 16);

cprintf ("SUFICIENTE"); }

else if (nota >= 3.5) {

textattr (YELLOW | BLINK | RED * 16);

cprintf ("INSUFICIENTE"); }

else {

textattr (YELLOW | BLINK | RED * 16);

cprintf ("MUY DEFICIENTE");

}

textattr (LIGHTGRAY | BLACK * 16);

}

/* Capítulo 5. Ejercicio 2 */

#include <stdio.h>

#include <conio.h>

main ()

{

char sexo;

int edad, t_calificacion, t_anterior;

clrscr ();

puts ("MARATÓN");

do {

printf ("\n(H)ombre / (M)ujer: ");

sexo = getche ();

} while (sexo != 'H' && sexo != 'M');

if (sexo == 'M') t_calificacion = 180;

else {

printf ("\nEdad: ");

scanf ("%d", &edad);

if (edad < 40) t_calificacion = 150;

else t_calificacion = 175;

}

printf ("\nTiempo de anterior Maratón: ");

scanf ("%d", &t_anterior);

if (t_anterior <= t_calificacion) puts ("SELECCIONADO");

else puts ("NO SELECCIONADO");

}

/* Capítulo 5. Ejercicio 3 */

#include <stdio.h>

#include <conio.h>

main ()

{

char turno, domingo;

int valor_hora, incremento, trabajadas;

clrscr ();

puts ("CÁLCULO DEL JORNAL");

do {

printf ("\n(D)iurno / (N)octurno: ");

turno = getche ();

} while (turno != 'D' && turno != 'N');

if (turno == 'D') {

valor_hora = 1000;

incremento = 400; }

else {

valor_hora = 1600;

incremento = 600;

}

do {

printf ("\nDomingo (S/N): ");

domingo = getche ();

} while (domingo != 'S' && domingo != 'N');

if (domingo == 'S') valor_hora += incremento;

printf ("\nHoras trabajadas: ");

scanf ("%d", &trabajadas);

printf ("\nJORNAL: %d pts.", valor_hora * trabajadas);

}

/* Capítulo 5. Ejercicio 4 */

#include <stdio.h>

#include <conio.h>

main ()

{

register int i;

int A, B, pares, impares;

clrscr ();

puts ("Suma de pares e impares comprendidos entre A y B");

do {

printf ("\nTeclee valores de A y B (A < B): ");

scanf ("%d %d", &A, &B);

} while (A >= B);

pares = impares = 0;

for (i = A; i <= B; i++) {

if (i % 2) impares += i;

else pares += i;

}

printf ("\nSUMA PARES: %d", pares);

printf ("\nSUMA IMPARES: %d", impares);

}

/* Capítulo 5. Ejercicio 5 */

#include <stdio.h>

#include <conio.h>

main ()

{

register int i;

int x, n;

long int total = 1;

clrscr ();

puts ("CÁLCULO DE xn");

printf ("\nValor de x: ");

scanf ("%d", &x);

do {

printf ("\nValor de n (n * 0): ");

scanf ("%d", &n);

} while (n < 0);

for (i = 1; i <= n; i++) total *= x;

printf ("\nResultado: %ld", total);

}

/* Capítulo 5. Ejercicio 6 */

#include <stdio.h>

#include <conio.h>

main ()

{

register int i;

int n;

long int total = 1;

clrscr ();

puts ("CÁLCULO DE n!");

do {

printf ("\nValor de n (n * 0): ");

scanf ("%d", &n);

} while (n < 0);

for (i = 1; i <= n; i++) total *= i;

printf ("\n%d! = %ld", n, total);

}

/* Capítulo 5. Ejercicio 7 */

#include <stdio.h>

#include <conio.h>

main ()

{

register int i;

int M;

long int suma = 0;

clrscr ();

puts ("Cálculo del primer valor N para el que 1 + 2 + 3 + ... + N > M");

do {

printf ("\nM = ");

scanf ("%d", &M);

} while (M < 0);

for (i = 1; ; i++) {

if (suma > M) break;

suma += i;

}

printf ("\nPara %d la suma vale %d", i - 1, suma);

}

/* Capítulo 5. Ejercicio 8 */

#include <stdio.h>

#include <conio.h>

main ()

{

int a_2, a_1, a, N;

clrscr ();

puts ("Primer elemento de la serie de Fibonacci mayor que N");

do {

printf ("\nValor de N (N > 1): ");

scanf ("%d", &N);

} while (N <= 1);

a_2 = a_1 = 1;

a = a_2 + a_1;

while (a <= N) {

a_2 = a_1;

a_1 = a;

a = a_1 + a_2;

}

printf ("\nEl primer elemento mayor que %d es %d", N, a);

}

/* Capítulo 5. Ejercicio 9 */

#include <stdio.h>

#include <conio.h>

double Valor_absoluto (double x);

main ()

{

register int i;

int signo;

double termino, mi_pi, pi_real;

clrscr ();

puts ("CALCULO DE π");

pi_real = 3.141592;

mi_pi = 0;

termino = 0;

signo = 1;

for (i = 1; ; i += 2) {

if (Valor_absoluto (pi_real - mi_pi) < 0.001) break;

termino += (double) signo / i;

mi_pi = 4 * termino;

signo = -signo;

gotoxy (1, 4);

printf ("Iteración: %5d - Valor estimado de π: %6.4f", i, mi_pi);

}

}

double Valor_absoluto (double x)

{

if (x < 0) return -x;

else return x;

}

6. Funciones

/* Capítulo 6. Ejercicio 1 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <stdlib.h>

double potencia (double base, int exponente);

double factorial (int numero);

void main (void)

{

register int i;

int x, signo;

double radianes, seno, termino;

clrscr ();

do {

printf ("\nÁngulo (0-360): ");

scanf ("%d", &x);

} while (x < 0 || x > 360);

radianes = x * 3.1416 / 180;

seno = 0;

signo = 1;

for (i = 1; ; i += 2) {

if (termino <= 0.001 && i != 1) break;

termino = potencia (radianes, i) / factorial (i);

seno += signo * termino;

signo = -signo;

gotoxy (1, 3);

printf ("\nTérmino: %6.4f - seno (%3d) = %6.4f", termino, x, seno);

}

}

double potencia (double base, int exponente)

{

register int i;

double total = 1;

for (i = 1; i <= exponente; i++) total *= base;

return total;

}

double factorial (int numero)

{

register int i;

double total = 1;

for (i = 1; i <= numero; i++) total *= (double) i;

return total;

}

/* Capítulo 6. Ejercicio 2 */

#include <stdio.h>

#include <conio.h>

long potencia (int base, int exponente);

void main (void)

{

int x, n;

clrscr ();

puts ("CÁLCULO DE xn MEDIANTE UNA FUNCIÓN RECURSIVA");

do {

printf ("\nValor de x (x > 0): ");

scanf ("%d", &x);

} while (x <= 0);

do {

printf ("\nValor de n (n > 0): ");

scanf ("%d", &n);

} while (n <= 0);

printf ("\nResultado: %ld", potencia (x, n));

}

long potencia (int base, int exponente)

{

if (!exponente) return 1;

return base * potencia (base, exponente - 1);

}

/* Capítulo 6. Ejercicio 3 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <stdlib.h>

int Fibonacci (int elemento);

void main (void)

{

register int i;

int N;

clrscr ();

puts ("SUCESIÓN DE FIBONACCI");

printf ("\nMostrar los N primeros términos");

do {

printf ("\nValor de N (N > 0): ");

scanf ("%d", &N);

} while (N <= 0);

for (i = 1; i <= N; i++) printf ("\n%d", Fibonacci (i));

}

int Fibonacci (int elemento)

{

if (elemento <= 2) return 1;

else return Fibonacci (elemento - 1) + Fibonacci (elemento - 2);

}

/* Capítulo 6. Ejercicio 4 */

#include <stdio.h>

#include <conio.h>

#include <bios.h>

void Presentar (void);

void main (void)

{

int equipo, a;

clrscr ();

Presentar ();

equipo = biosequip ();

gotoxy (37, 4);

a = equipo & 0x0002;

if (a) puts ("SI");

else puts ("NO");

gotoxy (37, 5);

a = (equipo & 0x000C) >> 2;

printf ("%d Kb.", (a + 1) * 16);

gotoxy (37, 7);

a = (equipo & 0x0030) >> 4;

switch (a) {

case 1: puts ("40x25 Blanco y Negro, Adaptador Color");

break;

case 2: puts ("80x25 Blanco y Negro, Adaptador Color");

break;

case 3: puts ("80x25 Adaptador Monocromo");

}

gotoxy (37, 8);

a = equipo & 0x0001;

if (!a) puts ("0");

else {

a = (equipo & 0x00C0) >> 6;

printf ("%d", a + 1);

}

gotoxy (37, 9);

a = equipo & 0x0100;

if (a) puts ("NO");

else puts ("SI");

gotoxy (37, 10);

a = (equipo & 0x0E00) >> 9;

printf ("%d", a);

gotoxy (37, 11);

a = equipo & 0x2000;

if (a) puts ("SI");

else puts ("NO");

gotoxy (37, 12);

a = (equipo & 0xC000) >> 14;

printf ("%d", a);

gotoxy (37, 6);

a = biosmemory ();

printf ("%d Kb.", a);

}

void Presentar (void)

{

puts ("EQUIPAMIENTO");

puts ("-----------------------\n");

puts ("Procesador matemático instalado ...");

puts ("RAM en placa base ...........................");

puts ("RAM convencional ...........................");

puts ("Modo inicial de vídeo .......................");

puts ("Unidades de disquete ......................");

puts ("Chip DMA instalado .........................");

puts ("Puertos serie ....................................");

puts ("Adaptador de juegos instalado .......");

puts ("Impresoras .......................................");

}

/* Capítulo 6. Ejercicio 5 */

#include <stdio.h>

#include <conio.h>

#include <bios.h>

void Presentar (void);

void main (void)

{

register int i;

unsigned int teclado, bit, salir = 0;

_setcursortype (_NOCURSOR);

clrscr ();

Presentar ();

for (;;) {

teclado = bioskey (2);

for (i = 0; i < 8; i++) {

bit = teclado & 1;

gotoxy (26, i + 1);

if (bit) puts ("SI");

else puts ("NO");

teclado >>= 1;

}

if (kbhit()) salir = getch ();

if (salir == 27) break;

}

_setcursortype (_NORMALCURSOR);

}

void Presentar (void)

{

puts ("Mayúsculas derecha ");

puts ("Mayúsculas izquierda ");

puts ("Tecla Control ");

puts ("Tecla Alt ");

puts ("Tecla Bloq Despl ");

puts ("Tecla Bloq Num ");

puts ("Tecla Bloq Mayús ");

puts ("Tecla Ins ");

puts ("\nPulse la tecla Esc para finalizar");

}

/* Capítulo 6. Ejercicio 6 */

char *Intro (int f, int c, int tam, char *cad)

{

register int i;

char aux[100];

gotoxy (c, f);

for (i = 0; i < tam; i++) putch (' ');

gotoxy (c, f);

aux[0] = tam + 1;

strcpy (cad, cgets (aux));

return cad;

}

/* Capítulo 6. Ejercicio 7 */

int Strdigit (char *cad)

{

register int i;

for (i = 0; cad[i]; i++) if (!isdigit (cad[i])) return 0;

return 1;

}

/* Capítulo 6. Ejercicio 8 */

char *Format_fecha (char *fecha, int tipo, char *format)

{

int diasemana;

char dia[3], mes[3], anyo[5], aux[9];

char meses[12][12] = { "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",

"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" };

char dias[7][12] = { "Domingo", "Lunes", "Martes", "Miércoles", "Jueves",

"Viernes", "Sábado" };

diasemana = Valida_fecha (fecha);

if (diasemana == -1 || tipo < 0 || tipo > 3) {

format = 0;

return format;

}

dia[2] = mes[2] = 0;

strncpy (dia, fecha, 2);

strncpy (mes, fecha + 2, 2);

strcpy (anyo, fecha + 4);

switch (tipo) {

case 0: sprintf (format, "%s/%s/%s", dia, mes, anyo + 2);

break;

case 1: sprintf (format, "%s/%s/%s", dia, mes, anyo);

break;

case 2: sprintf (format, "%d de %s de %s", atoi (dia), meses[atoi(mes) - 1], anyo);

break;

case 3: sprintf (format, "%s, %s", dias[diasemana], Format_fecha (fecha, 2, aux));

}

return format;

}

/* Capítulo 6. Ejercicio 9 */

#include <dos.h>

int Valida_fecha (char *fecha)

{

union REGS ent, sal;

char dia[3], mes[3], anyo[5];

int sysdia, sysmes, sysanyo, diasemana;

int i;

if (strlen (fecha) != 8) return -1;

for (i = 0; fecha[i]; i++) if (!isdigit (fecha[i])) return -1;

dia[2] = mes[2] = 0;

strncpy (dia, fecha, 2);

strncpy (mes, fecha + 2, 2);

strcpy (anyo, fecha + 4);

ent.h.ah =0x2A;

intdos (&ent, &sal);

sysanyo = sal.x.cx;

sysmes = sal.h.dh;

sysdia = sal.h.dl;

ent.h.ah = 0x2B;

ent.x.cx = atoi (anyo);

ent.h.dh = atoi (mes);

ent.h.dl = atoi (dia);

intdos (&ent, &sal);

if (sal.h.al) return -1;

ent.h.ah = 0x2A;

intdos (&ent, &sal);

diasemana = sal.h.al;

ent.h.ah = 0x2B;

ent.x.cx = sysanyo;

ent.h.dh = sysmes;

ent.h.dl = sysdia;

intdos (&ent, &sal);

return diasemana;

}

/* Capítulo 6. Ejercicio 10 */

int Tecla (int *scan)

{

unsigned palabra;

palabra = bioskey (0);

*scan = palabra >> 8;

return palabra & 0x00FF;

}

/* Capítulo 6. Ejercicio 11 */

int Mensaje (int st, int fil, int col, char *cad)

{

int ascii, scan;

gotoxy (col, fil);

cprintf (cad);

if (!st) return 0;

ascii = Tecla (&scan);

if (ascii) return ascii;

else return scan + 1000;

}

7. Matrices y punteros

/* Capítulo 7. Ejercicio 1 */

#include <stdio.h>

#include <conio.h>

int Suma_fila (int fila);

int Suma_columna (int columna);

int matriz[4][3];

void main (void)

{

register int i, j;

clrscr ();

puts ("Carga de los elementos de la matriz");

for (i = 0; i < 4; i++) {

for (j = 0; j < 3; j++) {

printf ("\nMATRIZ[%d][%d] = ", i, j);

scanf ("%d", &matriz[i][j]);

}

}

for (i = 0; i < 4; i++) printf ("\nLa fila %d suma %d", i, Suma_fila (i));

for (i = 0; i < 3; i++) printf ("\nLa columna %d suma %d", i, Suma_columna (i));

}

int Suma_fila (int fila)

{

register int i;

int total = 0;

for (i = 0; i < 3; i++) total += matriz[fila][i];

return total;

}

int Suma_columna (int columna)

{

register int i;

int total = 0;

for (i = 0; i < 4; i++) total += matriz[i][columna];

return total;

}

/* Capítulo 7. Ejercicio 2 */

#include <stdio.h>

#include <conio.h>

void main (void)

{

int magico[3][3];

int i, j, ant_i, ant_j;

register int valor;

clrscr ();

puts ("CUADRADO MÁGICO DE ORDEN 3");

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

magico[i][j] = 0;

}

}

i = 0;

j = 1;

for (valor = 1; valor <= 9; valor++) {

if (magico[i][j]) {

i = ant_i + 1;

j = ant_j;

if (i > 2) i = 0;

}

magico[i][j] = valor;

ant_i = i--;

ant_j = j++;

if (i < 0) i = 2;

if (j > 2) j = 0;

}

clrscr ();

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

printf ("%3d ", magico[i][j]);

}

printf ("\n");

}

}

/* Capítulo 7. Ejercicio 3

Se supone que en el directorio C:\MILIB se encuentran las funciones Intro()

y Strdigit() diseñadas en el capítulo anterior */

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <process.h>

#include "C:\MILIB\INTRO.C"

#include "C:\MILIB\STRDIGIT.C"

void main (int argc, char *argv[ ])

{

int magico[19][19];

int i, j, ant_i, ant_j, orden, tope;

register int valor;

clrscr ();

puts ("CUADRADO MÁGICO DE ORDEN N IMPAR (3 * N * 19)");

switch (argc) {

case 1: puts ("Falta parámetro");

exit (1);

case 2: orden = atoi (argv[1]);

if (orden < 3 || orden > 19 || !(orden % 2)) {

puts ("Parámetro no válido");

exit (1);

}

break;

default: puts ("Demasiados parámetros");

exit (1);

}

tope = orden * orden;

for (i = 0; i < orden; i++) {

for (j = 0; j < orden; j++) {

magico[i][j] = 0;

}

}

i = 0;

j = orden / 2;

for (valor = 1; valor <= tope; valor++) {

if (magico[i][j]) {

i = ant_i + 1;

j = ant_j;

if (i > orden - 1) i = 0;

}

magico[i][j] = valor;

ant_i = i--;

ant_j = j++;

if (i < 0) i = orden - 1;

if (j > orden - 1) j = 0;

}

clrscr ();

for (i = 0; i < orden; i++) {

for (j = 0; j < orden; j++) {

printf ("%3d ", magico[i][j]);

}

printf ("\n");

}

}

/* Capítulo 7. Ejercicio 4 */

/* Solución declarando las matrices como globales */

#include <stdio.h>

#include <conio.h>

void Carga (int x[3][3]);

int Producto (int fila, int columna);

int A[3][3], B[3][3];

void main (void)

{

register int i, j;

int P[3][3];

clrscr ();

puts ("Carga de la Matriz A");

Carga (A);

puts ("Carga de la Matriz B");

Carga (B);

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

P[i][j] = Producto (i, j);

}

}

puts ("Matriz producto: \n");

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

printf ("%3d ", P[i][j]);

}

printf ("\n");

}

}

void Carga (int x[3][3])

{

register int i, j;

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

printf ("\n[%d][%d]: ", i, j);

scanf ("%d", &x[i][j]);

}

}

}

int Producto (int fila, int columna)

{

register int k;

int total = 0;

for (k = 0; k < 3; k++) total += A[fila][k] * B[k][columna];

return total;

}

/* Capítulo 7. Ejercicio 4 */

/* Solución declarando las matrices como locales */

#include <stdio.h>

#include <conio.h>

void Carga (int x[3][3]);

int Producto (int fila, int columna, int x[3][3], int y[3][3]);

void main (void)

{

register int i, j;

int A[3][3], B[3][3], P[3][3];

clrscr ();

puts ("Carga de la Matriz A");

Carga (A);

puts ("Carga de la Matriz B");

Carga (B);

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

P[i][j] = Producto (i, j, A, B);

}

}

puts ("Matriz producto: \n");

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

printf ("%3d ", P[i][j]);

}

printf ("\n");

}

}

void Carga (int x[3][3])

{

register int i, j;

for (i = 0; i < 3; i++) {

for (j = 0; j < 3; j++) {

printf ("\n[%d][%d]: ", i, j);

scanf ("%d", &x[i][j]);

}

}

}

int Producto (int fila, int columna, int x[3][3], int y[3][3])

{

register int k;

int total = 0;

for (k = 0; k < 3; k++) total += x[fila][k] * y[k][columna];

return total;

}

/* Capítulo 7. Ejercicio 5 */

char *Strminus (char *cad)

{

char mayus[ ] = "ÁÉÍÓÚÀÈÌÒÙÄËÏÖÜÂÊÎÔÛÑÇ";

char minus[ ] = "áéíóúàèìòùäëïöüâêîôûñç";

char *p;

register int i;

strlwr (cad);

for (i = 0; cad[i]; i++) {

p = strchr (mayus, cad[i]);

if (p) cad[i] = minus[p - mayus];

}

return cad;

}

char *Strmayus (char *cad)

{

char mayus[ ] = "ÁÉÍÓÚÀÈÌÒÙÄËÏÖÜÂÊÎÔÛÑÇ";

char minus[ ] = "áéíóúàèìòùäëïöüâêîôûñç";

char *p;

register int i;

strupr (cad);

for (i = 0; cad[i]; i++) {

p = strchr (minus, cad[i]);

if (p) cad[i] = mayus[p - minus];

}

return cad;

}

/* Capítulo 7. Ejercicio 6 */

#include <stdio.h>

#include <conio.h>

#include <bios.h>

#include <time.h>

void Presentar (void);

void Iniciar (int vector[ ], int n);

void Burbuja (int vector[ ], int n);

void Seleccion (int vector[ ], int n);

void Insercion (int vector[ ], int n);

void Shell (int vector[ ], int n);

void Quick (int vector[ ], int primero, int ultimo);

void main (void)

{

int fila, x[5000];

register int i;

unsigned long int inicio, final;

clrscr ();

Presentar ();

fila = 6;

for (i = 500; i <= 5000; i += 500) {

Iniciar (x, i);

inicio = biostime (0, 0);

Burbuja (x, i);

final = biostime (0, 0);

gotoxy (9, fila);

printf ("%12lu ", final - inicio);

Iniciar (x, i);

inicio = biostime (0, 0);

Seleccion (x, i);

final = biostime (0, 0);

gotoxy (23, fila);

printf ("%12lu ", final - inicio);

Iniciar (x, i);

inicio = biostime (0, 0);

Insercion (x, i);

final = biostime (0, 0);

gotoxy (37, fila);

printf ("%12lu ", final - inicio);

Iniciar (x, i);

inicio = biostime (0, 0);

Shell (x, i);

final = biostime (0, 0);

gotoxy (51, fila);

printf ("%12lu ", final - inicio);

Iniciar (x, i);

inicio = biostime (0, 0);

Quick (x, 0, i - 1);

final = biostime (0, 0);

gotoxy (65, fila);

printf ("%12lu ", final - inicio);

fila += 2;

}

}

void Presentar (void)

{

register int i, j;

char titulos[ ][15] = { "BURBUJA", "SELECCIÓN", "INSERCIÓN", "SHELL", "QUICK" };

puts ("TICKS EMPLEADOS EN LAS DIFERENTES ORDENACIONES");

printf ("\n*******");

for (i = 1; i <= 5; i++) printf ("********");

putch ('*');

printf ("\n* ");

for (i = 1; i <= 5; i++) printf ("*%12s ", titulos[i - 1]);

putch ('*');

for (j = 500; j <= 5000; j += 500) {

printf ("\n****");

for (i = 1; i <= 5; i++) printf ("********");

putch ('*');

printf ("\n* %4d ", j);

for (i = 1; i <= 5; i++) printf ("* ");

putch ('*');

}

printf ("\n****");

for (i = 1; i <= 5; i++) printf ("********");

putch ('*');

}

void Iniciar (int vector[ ], int tope)

{

register int i;

for (i = 0; i < tope; i++) vector[i] = tope - i;

}

void Burbuja (int vector[ ], int tope)

{

int i, ordenado, aux;

ordenado = 0;

while (!ordenado) {

ordenado = 1;

for (i = 0; i < tope - 1; i++) {

if (vector[i] > vector[i + 1]) {

aux = vector[i];

vector[i] = vector[i + 1];

vector[i + 1] = aux;

ordenado = 0;

}

}

tope--;

}

}

void Seleccion (int vector[ ], int tope)

{

register int i, inicio;

int aux, menor;

for (inicio = 0; inicio < tope - 1; inicio++) {

menor = inicio;

for (i = inicio + 1; i < tope; i++) if (vector[i] < vector[menor]) menor = i;

aux = vector[inicio];

vector[inicio] = vector[menor];

vector[menor] = aux;

}

}

void Insercion (int vector[ ], int n)

{

register int i, j;

int aux;

for (i = 1; i < n; i++) {

aux = vector[i];

for (j = i - 1; j >= 0; j--) {

if (aux < vector[j]) vector[j + 1] = vector[j];

else break;

}

vector[j + 1] = aux;

}

}

void Shell (int vector[ ], int n)

{

register int i, separador;

int aux;

for (separador = n / 2; separador > 0; separador /= 2) {

if (!(separador % 2)) separador++;

for (i = 0; i < n - separador; i++) {

if (vector[i] > vector[i + separador]) {

aux = vector[i];

vector[i] = vector[i + separador];

vector[i + separador] = aux;

}

}

}

}

void Quick (int vector[ ], int primero, int ultimo)

{

register int i, j;

int aux, centro;

centro = vector[ (primero + ultimo) / 2];

i = primero;

j = ultimo;

do {

while (centro > vector[i]) i++;

while (vector[j] > centro) j--;

if (i < j) {

aux = vector[i];

vector[i] = vector[j];

vector[j] = aux;

i++;

j--; }

else if (i == j) i++;

} while (i <= j);

if (primero < j) Quick (vector, primero, j);

if (i < ultimo) Quick (vector, i, ultimo);

}

Los valores proporcionados son:

BURBUJA

SELECCIÓN

INSERCIÓN

SHELL

QUICK

500

10

4

6

0

0

1000

38

17

22

1

0

1500

87

41

54

1

1

2000

154

68

88

1

0

2500

242

109

139

1

1

3000

350

157

201

2

1

3500

477

213

274

2

2

4000

623

277

358

2

1

4500

789

346

453

3

2

5000

974

427

559

3

2

La primera columna indica el número de elementos a ordenar. En el interior se muestra los ticks transcurridos. Los métodos más eficientes son Shell y Quick y el peor es de la Burbuja. Si el vector está ordenado aleatoriamente el método de Inserción supera al de Selección. Las modificaciones que hay que hacer en el programa para que el vector esté ordenado aleatoriamente son:

  • Añadir las líneas que incluyen los archivos de cabecera stdlib.h y mem.h.

  • Eliminar la función Iniciar() y su prototipo.

  • Añadir las declaraciones int y[5000]; y register int j;.

  • Después de la línea for (i = 500; i <= 5000; i += 500) {, añadir:

randomize ();

for (j = 0; j < i; j++) y[j] = random (10000);

  • Sustituir todas las llamadas a Iniciar() por sentencias memcpy (x, y, 2 * i);

Los resultados proporcionados por este programa son los siguientes:

BURBUJA

SELECCIÓN

INSERCIÓN

SHELL

QUICK

500

7

5

3

0

0

1000

34

18

11

1

0

1500

64

41

25

1

1

2000

114

75

43

2

1

2500

180

116

70

2

1

3000

260

166

101

2

1

3500

351

225

134

3

2

4000

460

293

176

3

3

4500

583

370

225

3

3

5000

719

457

277

3

3

/* Capítulo 7. Ejercicio 7: Función Copia() con índices */

char *Copia (char *cad1, const char *cad2)

{

register int i;

for (i = 0; cad2[i]; i++) cad1[i] = cad2[i];

cad1[i] = 0;

return cad1;

}

/* Capítulo 7. Ejercicio 7: Función Copia() con punteros */

char *Copia (char *cad1, const char *cad2)

{

char *p1;

const char *p2;

for (p1 = cad1, p2 = cad2; *p2; p1++, p2++) *p1 = *p2;

*p1 = 0;

return cad1;

}

/* Capítulo 7. Ejercicio 7: Función Concatena() con índices */

char *Concatena (char *cad1, const char *cad2)

{

register int i, j;

for (i = 0, j = strlen (cad1); cad2[i]; i++, j++) cad1[j] = cad2[i];

cad1[j] = 0;

return cad1;

}

/* Capítulo 7. Ejercicio 7: Función Concatena() con punteros */

char *Concatena (char *cad1, const char *cad2)

{

char *p1;

const char *p2;

p1 = cad1 + strlen (cad1);

p2 = cad2;

for (; *p2; p1++, p2++) *p1 = *p2;

*p1 = 0;

return cad1;

}

/* Capítulo 7. Ejercicio 8: Función Insertar() con índices */

char *Insertar (char *cad, int car, int pos)

{

register int i;

for (i = strlen (cad); i >= pos; i--) cad[i + 1] = cad[i];

cad[pos] = car;

return cad;

}

/* Capítulo 7. Ejercicio 8: Función Insertar() con punteros */

char *Insertar (char *cad, int car, int pos)

{

char *p;

p = cad + strlen (cad);

for (; p >= cad + pos; p--) *(p + 1) = *p;

*(cad + pos) = car;

return cad;

}

/* Capítulo 7. Ejercicio 9: Función Elimina() con índices */

char *Elimina (char *cad, int pos)

{

register int i;

for (i = pos + 1; cad[i]; i++) cad[i - 1] = cad[i];

cad[i - 1] = 0;

return cad;

}

/* Capítulo 7. Ejercicio 9: Función Elimina() con punteros */

char *Elimina (char *cad, int pos)

{

char *p;

p = cad + pos + 1;

for (; *p; p++) *(p - 1) = *p;

*(p - 1) = 0;

return cad;

}

/* Capítulo 7. Ejercicio 10. Función Substr() con índices */

char *Substr (char *orig, int desde, int n, char *dest)

{

register int i, j;

for (i = desde, j = 0; i < desde + n && orig[i]; i++, j++) dest[j] = orig[i];

dest[j] = 0;

return dest;

}

/* Capítulo 7. Ejercicio 10: Función Substr() con punteros */

char *Substr (char *orig, int desde, int n, char *dest)

{

char *po, *pd;

po = orig + desde;

pd = dest;

while (po < orig + desde + n && *po) {

*pd = *po;

pd++;

po++;

}

*pd = 0;

return dest;

}

/* Capítulo 7. Ejercicio 11 */

#include <stdio.h>

#include <conio.h>

#include <time.h>

#define SI 1

#define NO 0

void main (void)

{

int x[1000], desorden, aux, *p, tope, i;

clock_t inicio, fin;

clrscr ();

puts ("ORDENACION MEDIANTE INDICES");

for (i = 0; i < 1000; i++) x[i] = 1000 - i;

puts ("Matriz cargada. Comienza ordenación");

inicio = clock ();

tope = 1000;

desorden = SI;

while (desorden) {

desorden = NO;

for (i = 0; i < tope - 1; i++) {

if (x[i] > x[i + 1]) {

aux = x[i];

x[i] = x[i + 1];

x[i + 1] = aux;

desorden = SI;

}

}

tope--;

}

fin = clock ();

printf ("Ordenación finalizada. Tiempo medido: %7.4f\n", (fin - inicio) / CLK_TCK);

puts ("\nORDENACION MEDIANTE PUNTEROS");

for (i = 0; i < 1000; i++) x[i] = 1000 - i;

puts ("Matriz cargada. Comienza ordenación");

inicio = clock ();

tope = 1000;

desorden = SI;

while (desorden) {

desorden = NO;

for (p = x; p < x + tope - 1; p++) {

if (*p > *(p + 1)) {

aux = *p;

*p = *(p + 1);

*(p + 1) = aux;

desorden = SI;

}

}

tope--;

}

fin = clock ();

printf ("Ordenación finalizada. Tiempo calculado: %7.4f", (fin - inicio) / CLK_TCK);

}

/* Capítulo 7. Ejercicio 12 */

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <time.h>

void main (void)

{

int vector[50], *p, mayor, lugar, *direccion, i;

clrscr ();

randomize ();

puts ("Carga aleatoria del vector");

for (p = vector; p < vector + 50; p++) *p = random (1000);

for (i = 0; i < 50; i++) {

if (i == 4 * (i / 4)) printf ("\n");

else printf (" ");

printf ("%2d - %3d [%ph]", i, vector[i], &vector[i]);

}

mayor = *vector;

lugar = 0;

direccion = vector;

for (p = vector + 1; p < vector + 50; p++) {

if (*p > mayor) {

mayor = *p;

lugar = p - vector;

direccion = p;

}

}

printf ("\n\nEl mayor es %d", mayor);

printf ("\nOcupa el lugar %d", lugar);

printf ("\nSe almacena en la dirección %p", direccion);

}

/* Capítulo 7. Ejercicio 13 */

#include <stdio.h>

#include <conio.h>

#define TOPE 50

int Menu (void);

int Mostrar (int);

int Introducir (int);

int Sacar (int);

int (*F_pila[ ]) (int) = { Mostrar, Introducir, Sacar };

int pila[TOPE], indice;

void main (void)

{

int n, dato, st;

while ((n = Menu ()) != 4) {

if (n == 2) {

printf ("\nDato a introducir en la pila: ");

scanf ("%d", &dato);

}

st = (*F_pila[n - 1]) (dato);

switch (n) {

case 2: if (st) puts ("\nPILA LLENA: El dato no se ha introducido");

case 1: break;

case 3: if (st < 0) puts ("\nPILA VACIA");

else printf ("\nDato sacado de la pila: %d", st);

}

printf ("\nPulse una tecla ...");

getch ();

}

}

int Menu (void)

{

int opcion;

clrscr ();

puts ("1. Mostrar el contenido de la pila");

puts ("2. Introducir un dato en la pila");

puts ("3. Sacar un dato de la pila");

puts ("4. Fin del programa");

do {

opcion = getch ();

} while (opcion < '1' || opcion > '4');

return opcion - 48;

}

int Mostrar (int x)

{

register int i;

for (i = 0; i < indice; i++) {

if (i == 5 * (i / 5)) printf ("\n");

else printf (" ");

printf ("%2d: %4d", i, pila[i]);

}

return 0;

}

int Introducir (int x)

{

if (indice == TOPE) return 1;

pila[indice++] = x;

return 0;

}

int Sacar (int x)

{

if (!indice) return -1;

return pila[--indice];

}

8. Otros tipos de datos

/* Capítulo 8. Ejercicio 1

Las funciones Intro() y Strdigit() se suponen almacenadas en módulos aparte, compiladas separadamente y enlazadas con este programa */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <math.h>

#define LF fprintf (stdprn, "\n\r");

#define FF fprintf (stdprn, "\f");

struct COMPO {

char codigo[9];

char cantidad;

int precio;

};

struct ARTIC {

char codigo[6];

char descri[41];

struct COMPO co[5];

};

char *Intro (int, int, int, char *);

int Strdigit (char *);

void Cabecera (void);

void main (void)

{

register int i, j, k;

struct ARTIC ar[25];

char cant[4], prec[5];

int articulos;

long total, parcial;

clrscr ();

textcolor (YELLOW);

textbackground (BLUE);

for (i = 0; i < 10; i++) {

printf ("\nARTICULO nº %d", i);

printf ("\nCódigo: (000 para acabar) ");

Intro (wherey (), wherex (), 5, ar[i].codigo);

if (!strcmp (ar[i].codigo, "000")) break;

printf ("\nDescripción: ");

Intro (wherey (), wherex (), 40, ar[i].descri);

for (j = 0; j < 5; j++) {

printf ("\nComponente nº %d", j);

printf ("\nCódigo: ");

Intro (wherey (), wherex (), 8, ar[i].co[j].codigo);

do {

do {

printf ("\nCantidad (1-100): ");

Intro (wherey (), wherex (), 3, cant);

} while (!Strdigit (cant));

} while (atoi (cant) < 1 || atoi (cant) > 100);

ar[i].co[j].cantidad = atoi (cant);

do {

do {

printf ("\nPrecio (500-5000): ");

Intro (wherey (), wherex (), 4, prec);

} while (!Strdigit (prec));

} while (atoi (prec) < 500 || atoi (prec) > 5000);

ar[i].co[j].precio = atoi (prec);

}

printf ("\n--------------------------------------------");

}

printf ("\nIMPRESIÓN DE DATOS. Prepare la impresora y pulse <Intro>");

while (getch () != 13);

articulos = 0;

for (k = 0; k < i; k++) {

if (!articulos) Cabecera ();

total = 0;

for (j = 0; j < 5; j++) {

parcial = (long) ar[k].co[j].cantidad * ar[k].co[j].precio;

total += parcial;

LF;

if (!j) fprintf (stdprn, "%-5s %-40s ", ar[k].codigo, ar[k].descri);

else fprintf (stdprn, "%5s %40s ", " ", " ");

fprintf (stdprn, "%-8s %3d %5d %6ld", ar[k].co[j].codigo, ar[k].co[j].cantidad, ar[k].co[j].precio, parcial);

}

LF; fprintf (stdprn, "%75s", "-------");

LF; fprintf (stdprn, "%50s Total .......... %7ld", " ", total);

LF;

LF;

articulos++;

if (articulos == 5) articulos = 0;

}

FF;

}

void Cabecera (void)

{

static int pagina;

register int i;

if (pagina) FF;

pagina++;

fprintf (stdprn, "%-64s Página:%3d", "QUIEBRA, S.A. Listado de precios", pagina);

LF;

LF; fprintf (stdprn, "%67s", "COMPONENTES");

LF; fprintf (stdprn, "%75s", "----------------------------");

LF; fprintf (stdprn, " COD %-40s CODIGO CANT PRECIO IMPORTE", "DESCRIPCION");

LF; for (i = 0; i < 75; i++) fprintf (stdprn, "-");

}

/* Capítulo 8. Ejercicio 2 */

#include <stdio.h>

#include <conio.h>

#include <dos.h>

struct IMPRESORA {

unsigned timeout: 1;

unsigned :2;

unsigned error_ES: 1;

unsigned conectada: 1;

unsigned sin_papel: 1;

unsigned ack: 1;

unsigned libre: 1;

};

union IMPR {

char x;

struct IMPRESORA im;

};

void main (void)

{

union REGS ent, sal;

union IMPR int17;

clrscr ();

puts ("DETERMINACIÓN DEL ESTADO DE LA IMPRESORA (LPT1:)");

ent.h.ah = 2;

ent.x.dx = 0;

int86 (0x17, &ent, &sal);

int17.x = sal.h.ah;

if (int17.im.timeout) puts ("La impresora no respondió en el tiempo previsto");

if (int17.im.error_ES) puts ("Error de E/S");

if (int17.im.conectada) puts ("Impresora seleccionada");

if (int17.im.sin_papel) puts ("No hay papel");

if (int17.im.ack) puts ("Reconocimiento de impresora (Acuse de recibo ACK)");

if (int17.im.libre) puts ("Impresora libre");

}

9. Asignación dinámica de memoria

/* Capítulo 9. Ejercicio 1 */

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <alloc.h>

struct PILA {

int dato;

struct PILA *enlace;

};

int Menu (void);

int Introducir (int n);

int Sacar (void);

struct PILA *primero;

void main (void)

{

int valor, opcion, st;

primero = 0;

while ((opcion = Menu ()) != 3) {

switch (opcion) {

case 1: printf ("\nValor a introducir en la pila: ");

scanf ("%d", &valor);

if (!Introducir (valor)) {

puts ("\nMemoria agotada. Pulse una tecla ...");

while (!getch ());

}

break;

case 2: valor = Sacar ();

if (valor < 0) puts ("\nPila vacía");

else printf ("\nValor obtenido: %d", valor);

printf ("\nPulse una tecla ...");

while (!getch ());

}

}

}

int Menu (void)

{

int n;

clrscr ();

puts ("PILA DINÁMICA\n");

puts ("1. Introducir");

puts ("2. Sacar");

puts ("3. Salir\n");

do {

n = getch ();

} while (n < '1' || n > '3');

return n - 48;

}

int Introducir (int n)

{

struct PILA *nuevo, *actual, *anterior;

nuevo = (struct PILA *) malloc (sizeof (struct PILA));

if (!nuevo) return 0;

nuevo -> dato = n;

nuevo -> enlace = 0;

if (!primero) primero = nuevo;

else {

actual = primero;

while (actual) {

anterior = actual;

actual = anterior -> enlace;

}

anterior -> enlace = nuevo;

}

return 1;

}

int Sacar (void)

{

struct PILA *actual, *anterior;

int n;

if (!primero) return -1;

actual = primero;

while (actual -> enlace) {

anterior = actual;

actual = anterior -> enlace;

}

n = actual -> dato;

if (primero -> enlace) anterior -> enlace = 0;

else primero = 0;

free (actual);

return n;

}

10. Ficheros

/* Capítulo 10. Ejercicio 1 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

void main (int argc, char *argv[ ])

{

FILE *f;

char caracter;

switch (argc) {

case 1: puts ("Falta el nombre del fichero");

exit (1);

case 2: if (!(f = fopen (argv[1], "wt"))) {

perror (argv[1]);

exit (1);

}

break;

default: puts ("Demasiados parámetros");

exit (1);

}

caracter = getche ();

while (caracter != 26) { //26 es el código ASCII de CTRL-Z

fputc (caracter, f);

if (ferror (f)) {

printf ("\nError de escritura en %s", argv[1]);

exit (1);

}

if (caracter == 13) {

putch ('\n');

fputc ('\12', f);

}

caracter = getche ();

}

fclose (f);

}

/* Capítulo 10. Ejercicio 2

Se utiliza la función rename (renombra ficheros) y la función remove (borra ficheros) */

#include <stdio.h>

#include <process.h>

#include <string.h>

#define CTRLZ 26

void main (int argc, char *argv[ ])

{

FILE *fe, *fs;

char reg[81], tmp[100], char *p;

int i, cambios = 0;

switch (argc) {

case 1:

case 2:

case 3: puts ("Falta algún parámetro");

exit (1);

case 4: if (!(fe = fopen (argv[1], "rt"))) {

perror (argv[1]);

exit (1);

}

break;

default: puts ("Demasiados parámetros");

exit (1);

}

if (!(fs = fopen ("tmp.tmp", "wt"))) {

puts ("Error al crear el fichero temporal");

exit (1);

}

fgets (reg, 80, fe);

while (!feof (fe)) {

p = strstr (reg, argv[2]);

while (p) {

cambios++;

for (i = 0; i < p - reg; i++) tmp[i] = reg[i];

tmp[i] = 0;

strcat (tmp, argv[3]);

strcat (tmp, p + strlen (argv[2]));

strcpy (reg, tmp);

p = strstr (reg, argv[2]);

}

fputs (reg, fs);

fgets (reg, 80, fe);

}

fclose (fe);

fclose (fs);

if (remove (argv[1]) == -1) puts ("No se pueden almacenar los cambios");

else if(rename ("tmp.tmp", argv[1])) puts ("Cambios se han almacenado en TMP.TMP");

printf ("\nCambios: %d", cambios);

}

/* Capítulo 10. Ejercicio 3 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <string.h>

#define LF fprintf (stdprn, "\n\r");

#define FF fprintf (stdprn, "\f");

struct REG {

char nom[41];

float alt;

char pro[26];

};

void Cabecera (char *, float);

char *Intro (int, int, int, char *);

void main (void)

{

FILE *f;

struct REG al;

char provincia[26];

char nombre[500][41];

float altura[500], total = 0, media;

register int i;

int linea = 0, contador = 0;

if (!(f = fopen ("B:ALTOS.DAT", "rb"))) {

perror ("ALTOS.DAT");

exit (1);

}

printf ("\nProvincia: ");

Intro (wherey (), wherex (), 25, provincia);

strupr (provincia);

fread (&al, sizeof (al), 1, f);

while (!feof (f)) {

if (!strcmp (provincia, al.pro)) {

strcpy (nombre[contador], al.nom);

altura[contador] = al.alt;

contador++;

total += al.alt;

}

fread (&al, sizeof (al), 1, f);

}

if (contador) {

media = total / contador;

for (i = 0; i < contador; i++) {

if (altura[i] > media) {

if (!linea) Cabecera (provincia, media);

LF; fprintf (stdprn, "%-40s %4.2f", nombre[i], altura[i]);

linea++;

if (linea == 50) linea = 0;

}

}

FF; }

else puts ("\nNo hay datos de esta provincia");

fclose (f);

}

void Cabecera (char *prov, float med)

{

static int pagina;

if (pagina) FF;

pagina++;

LF; fprintf (stdprn, "Provincia: %s", prov);

LF; fprintf (stdprn, "Altura Media: %4.2f", med);

LF;

LF; fprintf (stdprn, "Nombre Altura");

LF; fprintf (stdprn, " ");

}

/* Capítulo 10. Ejercicio 4 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <stdlib.h>

#include <dos.h>

#define LF fprintf (stdprn, "\n\r")

#define FF fprintf (stdprn, "\f")

struct ARTIC {

char cod[7];

char des[31];

unsigned exi;

unsigned pco;

unsigned pvp;

char pro[5];

};

char *Intro (int, int, int, char *);

int Strdigit (char *);

void Cabecera (void);

void Linea (void);

void Fecha ();

char fec[20];

void main (void)

{

FILE *fart, *fnp;

struct ARTIC ar;

char nompro[41];

char articulo[7], arini[7], arfin[7];

int linea = 0, sw = 0;

long nreg;

unsigned long coste, venta, difer, t_coste = 0, t_venta = 0;

if (!(fart = fopen ("B:ARTIC.DAT", "rb"))) {

perror ("ARTIC.DAT");

exit (1);

}

if (!(fnp = fopen ("B:NOMPRO.DAT", "rb"))) {

perror ("NOMPRO.DAT");

exit (1);

}

Fecha ();

do {

do {

printf ("\nArtículo Inicial: ");

Intro (wherey (), wherex (), 6, articulo);

} while (!Strdigit (articulo));

sprintf (arini, "%06d", atoi (articulo));

do {

printf ("\nArtículo Final: ");

Intro (wherey (), wherex (), 6, articulo);

} while (!Strdigit (articulo));

sprintf (arfin, "%06d", atoi (articulo));

} while (strcmp (arini, arfin) > 0);

do {

fread (&ar, sizeof (ar), 1, fart);

} while (!feof (fart) && strcmp (ar.cod, arini) < 0);

while (!feof (fart) && strcmp (ar.cod, arfin) <= 0) {

if (!linea) Cabecera ();

nreg = (atoi (ar.pro) - 1) * sizeof (nompro);

fseek (fnp, nreg, SEEK_SET);

fread (&nompro, sizeof (nompro), 1, fnp);

if (ferror (fnp)) strcpy (nompro, "Desconocido");

coste = (unsigned long) ar.exi * ar.pco;

venta = (unsigned long) ar.exi * ar.pvp;

difer = venta - coste;

t_coste += coste;

t_venta += venta;

LF; fprintf (stdprn, "%6s-%-30s %5u %5u %9lu %5u %9lu %9lu %5s-%-40s", /

ar.cod, ar.des, ar.exi, ar.pco, coste, ar.pvp, venta, difer, ar.pro, nompro);

sw = 1;

linea++;

if (linea == 50) linea = 0;

fread (&ar, sizeof (ar), 1, fart);

}

if (sw) {

LF; fprintf (stdprn, "%85s", "--------- --------- ---------");

difer = t_venta - t_coste;

LF; fprintf (stdprn, "%49s %9lu %9lu %9lu", "Totales .....", t_coste, t_venta, difer);

FF;

}

fclose (fart);

fclose (fnp);

}

void Cabecera (void)

{

static int pagina;

if (pagina) FF;

pagina++;

LF; fprintf (stdprn, "%-84s Fecha: %-18s Página:%3d", "INVENTARIO /

VALORADO A PRECIO DE COSTE Y DE VENTA", fec, pagina);

LF;

LF; Linea ();

LF; fprintf (stdprn, "%-37s Exist Valor a P.Coste Valor a P.Venta Diferenc. /

Proveedor", "Artículo");

LF; Linea ();

}

void Linea (void)

{

register int i;

for (i = 0; i < 132; i++) fprintf (stdprn, "=");

}

void Fecha (void)

{

char meses[12][11] = { "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",

"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" };

struct date f;

getdate (&f);

sprintf (fec, "%d-%s-%d", f.da_day, meses[f.da_mon - 1], f.da_year);

}

11. Ficheros indexados: la interfase Btrieve

/* Capítulo 11. Ejercicio 1

Se utilizan las funciones Intro y Strdigit diseñadas en el Capítulo 6

Se supone que se compilan por separado y se enlazan posteriormente */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <process.h>

#include <c:\btr\turcbtrv.c>

#define ABRIR 0

#define CERRAR 1

#define IGUAL 5

#define SIGUIENTE 6

#define MAY_IGUAL 9

#define AL 0

#define GR 1

#define NF 2

#define LF fprintf (stdprn, "\n\r")

#define FF fprintf (stdprn, "\f")

struct REG_AL {

char gru[6];

char nom[31];

int fal[12][8];

};

struct REG_GR {

char gru[6];

char asg[8][6];

};

union REG_TOT {

struct REG_AL al;

struct REG_GR gr;

};

char bloque[NF][128];

union REG_TOT area[NF];

int longitud[NF] = { sizeof (struct REG_AL), sizeof (struct REG_GR) };

char clave[NF][37];

int nclave[NF] = { 1, 0 };

char fichero[NF][13] = { "ALUMNOS.BTR", "GRUPO.BTR" };

int faltasig[8];

char *Intro (int, int, int, char *);

int Strdigit (char *);

int Btr (int, int);

void BtrError (int, int, int);

void Cerrar (int);

void Cabecera (char *, char *);

void Detalle (int);

void Pie (void);

void Linea (void);

void main (void)

{

int i, p, nmes, st, impresion = 0, linea = 0;

char grupo[6], mes[3];

char grupos[6][6] = { "1FP2B", "2FP2A", "2FP2B", "2FP2C", "3FP2A", "3FP2B" };

char meses[12][12] = { "ENERO", "FEBRERO", "MARZO", "ABRIL", "MAYO", "JUNIO",

"JULIO", "AGOSTO", "SEPTIEMBRE", "OCTUBRE", "NOVIEMBRE", "DICIEMBRE" };

for (i = 0; i < NF; i++) {

strcpy (clave[i], fichero[i]);

st = Btr (ABRIR, i);

if (st) {

BtrError (i, st, ABRIR);

Cerrar (i);

exit (1);

}

}

clrscr ();

do {

printf ("\nGRUPOS: 1FP2B - 2FP2A - 2FP2B - 2FP2C - 3FP2A - 3FP2B ");

printf ("\nSeleccione grupo: ");

Intro (wherey (), wherex (), 5, grupo);

strupr (grupo);

for (i = 0; i < 6; i++) {

p = strcmp (grupo, grupos[i]);

if (!p) break;

}

} while (p);

do {

do {

printf ("\nMes: ");

Intro (wherey (), wherex (), 2, mes);

} while (!Strdigit (mes));

nmes = atoi (mes);

} while (nmes < 0 || nmes > 12);

printf (" - %s", meses[nmes - 1]);

strcpy (clave[GR], grupo);

st = Btr (IGUAL, GR);

if (st) {

printf ("\nNo hay datos de asignaturas");

while (!getch ());

for (i = 0; i < 6; i++) sprintf (area[GR].gr.asg[i], "ASG-%d", i + 1);

}

for (i = 0; i < 8; i++) faltasig[i] = 0;

sprintf (clave[AL], "%s%c%30s", grupo, 0, " ");

st = Btr (MAY_IGUAL, AL);

while (!st && !strcmp (grupo, area[AL].al.gru)) {

impresion = 1;

if (!linea) Cabecera (grupo, meses[nmes - 1]);

Detalle (nmes);

linea++;

if (linea > 55) linea = 0;

st = Btr (SIGUIENTE, AL);

if (st) st += 1000;

}

if (st && st != 9 && st < 1000) BtrError (AL, st, MAY_IGUAL);

else if (st && st != 1009) BtrError (AL, st - 1000, SIGUIENTE);

if (impresion) Pie ();

Cerrar (NF);

}

/*************************************** F U N C I O N E S ***************************************/

// Hace las llamadas a Btrieve

int Btr (int op, int nf)

{

return BTRV (op, bloque[nf], &area[nf], &longitud[nf], clave[nf], nclave[nf]);

}

// Muestra mensajes de error Btrieve

void BtrError (int nf, int st, int op)

{

printf ("\n%s: Error %d - Operación %d", fichero[nf], st, op);

while (!getch ());

}

// Cierra ficheros

void Cerrar (int nf)

{

int i, st;

for (i = 0; i < nf; i++) {

st = Btr (CERRAR, i);

if (st) BtrError (i, st, CERRAR);

}

}

// Imprime la cabecera del listado

void Cabecera (char *gr, char *month)

{

static int pagina;

int i;

if (pagina) FF;

pagina++;

LF; fprintf (stdprn, "CAPÍTULO 12. Ejercicio 1. Página:%2d", pagina);

LF; fprintf (stdprn, " ");

LF;

LF; fprintf (stdprn, "GRUPO: %s", gr);

LF; fprintf (stdprn, "FALTAS DEL MES DE %s", month);

LF;

LF; fprintf (stdprn, "%-30s", "Apellidos y nombre");

for (i = 0; i < 8; i++) fprintf (stdprn, "%6s", area[GR].gr.asg[i]);

fprintf (stdprn, " TOTAL");

LF; Linea ();

}

// Imprime la línea de detalle

void Detalle (int n)

{

int i, faltalum = 0;

LF; fprintf (stdprn, "%-30s", area[AL].al.nom);

for (i = 0; i < 8; i++) {

fprintf (stdprn, "%5d ", area[AL].al.fal[n - 1][i]);

faltalum += area[AL].al.fal[n - 1][i];

faltasig[i] += area[AL].al.fal[n - 1][i];

}

fprintf (stdprn, "%5d", faltalum);

}

// Imprime el pie del listado

void Pie (void)

{

int i, total = 0;

LF; Linea ();

LF; fprintf (stdprn, "%30s", "TOTALES:");

for (i = 0; i < 8; i++) {

fprintf (stdprn, "%5d ", faltasig[i]);

total += faltasig[i];

}

fprintf (stdprn, "%5d", total);

FF;

}

// Imprime una línea con el carácter =

void Linea (void)

{

int i;

for (i = 0; i < 84; i++) fprintf (stdprn, "=");

}

/* Capítulo 11. Ejercicio 2 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <string.h>

#include <dos.h>

#include <c:\btr\turcbtrv.c>

#define ABRIR 0

#define CERRAR 1

#define IGUAL 5

#define SIGUIENTE 6

#define MAY_IGUAL 9

#define PR 0

#define LI 1

#define AL 2

#define NF 3

#define LF fprintf (stdprn, "\n\r")

#define FF fprintf (stdprn, "\f")

struct REG_PR {

char fec[9];

char isbn[11];

char exp[6];

char dev;

};

struct REG_LI {

char isbn[11];

char tit[51];

char aut[31];

char edi[31];

};

struct REG_AL {

char exp[6];

char nom[31];

char gru[11];

};

union REG_TOT {

struct REG_PR pr;

struct REG_LI li;

struct REG_AL al;

};

char bloque[NF][128];

union REG_TOT area[NF];

int longitud[NF] = {sizeof (struct REG_PR), sizeof (struct REG_LI), sizeof (struct REG_AL) };

char clave[NF][13];

int nclave[NF] = { 1, 0, 0 };

char fichero[NF][13] = { "PRESTAMO.BTR", "LIBROS.BTR", "ALUMNOS.BTR" };

int ndia, nmes, nanyo;

int Btr (int, int);

void BtrError (int, int, int);

void Cerrar (int);

void Fecha (char *);

void FechaTope (char *, char *);

void DatosLibro (void);

void DatosAlumno (void);

void Imprimir (void);

void Formatea (char *);

void Linea (int);

void main (void)

{

int st, i, linea = 0, impresion = 0;

char tope[9], hoy[9];

for (i = 0; i < NF; i++) {

strcpy (clave[i], fichero[i]);

st = Btr (ABRIR, i);

if (st) {

BtrError (i, st, ABRIR);

Cerrar (i);

exit (1);

}

}

Fecha (hoy);

clave[PR][0] = 'N';

st = Btr (MAY_IGUAL, PR);

while (!st && area[PR].pr.dev == 'N') {

FechaTope (area[PR].pr.fec, tope);

if (strcmp (tope, hoy) < 0) {

DatosLibro ();

DatosAlumno ();

Imprimir ();

linea++;

if (linea > 5) {

linea = 0;

FF;

}

}

st = Btr (SIGUIENTE, PR);

if (st) st += 1000;

}

switch (st) {

case 0:

case 9:

case 1009: break;

default: if (st > 1000) BtrError (PR, st - 1000, SIGUIENTE);

else BtrError (PR, st, MAY_IGUAL);

}

if (!impresion) FF;

else printf ("\nNo hay devoluciones pendientes");

Cerrar (NF);

}

/********************************** F U N C I O N E S *****************************************/

// Hace las llamadas a Btrieve

int Btr (int op, int nf)

{

return BTRV (op, bloque[nf], &area[nf], &longitud[nf], clave[nf], nclave[nf]);

}

// Muestra los mensajes de error Btrieve

void BtrError (int nf, int st, int op)

{

printf ("\n%s: Error %d - Operación %d", fichero[nf], st, op);

while (!getch ());

}

// Cierra ficheros

void Cerrar (int nf)

{

int i, st;

for (i = 0; i < nf; i++) {

st = Btr (CERRAR, i);

if (st) BtrError (i, st, CERRAR);

}

}

// Obtiene la fecha del día en formato AAAAMMDD

void Fecha (char *cad)

{

struct date f;

getdate (&f);

sprintf (cad, "%d%02d%02d", f.da_year, f.da_mon, f.da_day);

}

// Calcula la fecha tope hasta la que se puede tener el libro prestado

void FechaTope (char *desde, char *hasta)

{

int dia, mes, anyo;

char xdia[3], xmes[3], xanyo[5];

int dias[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

xmes[2] = xanyo[4] = 0;

strcpy (xdia, desde + 6);

strncpy (xmes, desde +4, 2);

strncpy (xanyo, desde, 4);

ndia = dia = atoi (xdia);

nmes = mes = atoi (xmes);

nanyo = anyo = atoi (xanyo);

dia += 7;

if (dia > dias[mes - 1]) {

dia -= dias[mes - 1];

mes++;

if (mes > 12) {

mes = 1;

anyo++;

}

}

sprintf (hasta, "%d%02d%02d", anyo, mes, dia);

}

// Obtiene los datos del fichero LIBROS.BTR

void DatosLibro (void)

{

int st;

strcpy (clave[LI], area[PR].pr.isbn);

st = Btr (IGUAL, LI);

if (st) {

strcpy (area[LI].li.tit, "Sin datos");

strcpy (area[LI].li.aut, "Sin datos");

strcpy (area[LI].li.edi, "Sin datos");

}

}

// Obtiene los datos del fichero ALUMNOS.BTR

void DatosAlumno (void)

{

int st;

strcpy (clave[AL], area[PR].pr.exp);

st = Btr (IGUAL, AL);

if (st) {

strcpy (area[AL].al.nom, "Sin datos");

strcpy (area[AL].al.gru, "Sin datos");

}

}

// Imprime una ficha

void Imprimir (void)

{

char fecformat[30];

Formatea (fecformat);

LF; Linea ('=');

LF; fprintf (stdprn, "ALUMNO: %-30s GRUPO: %s", area[AL].al.nom, area[AL].al.gru);

LF; Linea ('-');

LF; fprintf (stdprn, "TÍTULO: %s", area[LI].li.tit);

LF; fprintf (stdprn, "AUTOR: %s", area[LI].li.aut);

LF; fprintf (stdprn, "EDITORIAL: %s", area[LI].li.edi);

LF; Linea ('-');

LF; fprintf (stdprn, "FECHA DEL PRÉSTAMO: %s", fecformat);

LF;

}

// Formatea la fecha del préstamo a DD de MMMMMMMMMM de AAAA

void Formatea (char *cad)

{

char meses[12][12] = { "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",

"Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" };

sprintf (cad, "%d de %s de %d", ndia, meses[nmes - 1], nanyo);

}

// Imprime una línea

void Linea (int trazo)

{

int i;

for (i = 0; i < 56; i++) fprintf (stdprn, "%c", trazo);

}

/* Capítulo 11. Ejercicio 3 */

#include <stdio.h>

#include <conio.h>

#include <process.h>

#include <string.h>

#include <c:\btr\turcbtrv.c>

#define ABRIR 0

#define CERRAR 1

#define ACTUALIZAR 3

#define BORRAR 4

#define IGUAL 5

struct REG_MV {

char alm[3];

char art[7];

unsigned can;

char ope;

};

struct REG_AR {

char alm[3];

char art[7];

char des[41];

int exi;

unsigned min;

unsigned opt;

unsigned pvp;

unsigned pco;

};

char bloque[128];

struct REG_AR ar;

int longitud = sizeof (ar);

char clave[13];

int Btr (int);

void BtrError (int, int);

void main (void)

{

FILE *MV;

struct REG_MV mv;

int st, op;

MV = fopen ("MOVIM.TMP", "rb");

if (!MV) {

perror ("MOVIM.TMP");

exit (1);

}

strcpy (clave, "ARTIC.BTR");

st = Btr (ABRIR);

if (st) {

BtrError (st, ABRIR);

exit (1);

}

clrscr ();

fread (&mv, sizeof (mv), 1, MV);

while (!feof (MV) && !ferror (MV)) {

printf ("\n%s %s %u %c", mv.alm, mv.art, mv.can, mv.ope);

strcpy (clave, mv.alm);

strcpy (clave + 3, mv.art);

st = Btr (IGUAL);

if (st) BtrError (st, IGUAL);

else {

switch (mv.ope) {

case 'E': ar.exi += mv.can;

op = ACTUALIZAR;

break;

case 'S': ar.exi -= mv.can;

op = ACTUALIZAR;

break;

case 'B': op = BORRAR;

}

st = Btr (op);

if (st) BtrError (st, op);

else printf (" Ok");

}

fread (&mv, sizeof (mv), 1, MV);

}

if (ferror (MV)) perror ("MOVIM.TMP");

fclose (MV);

st = Btr (CERRAR);

if (st) BtrError (st, CERRAR);

}

/************************************** F U N C I O N E S **************************************/

// Efectúa las operaciones Btrieve

int Btr (int op)

{

return BTRV (op, bloque, &ar, &longitud, clave, 0);

}

// Muestra los mensajes de error Btrieve

void BtrError (int st, int op)

{

printf ("\nARTIC.BTR: Error %d - Operación %d", st, op);

while (!getch ());

}

260 Introducción al Lenguaje C

14. Soluciones a los ejercicios 259