<div dir="ltr">Para crear un programa "a prueba de balas", es decir, que solo acepte determinados tipos de valores se utiliza un bucle, que puede ser while y algunos métodos de la clase istream. Me parece que te serviría un poco de lectura para no desaprovechar esta posibilidad de aprender que tienes. Por lo demás,<div><br></div><div>¡Felcitaciones! solo llegan los que perseveran. La inteligencia no es algo exclusivo de algunos, sino de aquellos que saben lo que quieren.<div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">El 7 de octubre de 2014, 17:26, marcelinux <span dir="ltr"><<a href="mailto:marcelinator@gmail.com" target="_blank">marcelinator@gmail.com</a>></span> escribió:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hola a todos.<br>
Ya os habréis dado cuenta de que vervose es un "gazapo", pero cumplió su misión.<br>
He implementado una nueva versión de la división.<br>
Esta vez he creado una clase que simula una hoja cuadriculada donde se "pintará" la división.<br>
Para eso ya he usado dos archivos (definición y declaración), más el archivo con el main().<br>
Para la próxima versión, controlaré que sólo se permita introducir números.<br>
La siguiente, admitirá las cantidades como argumentos del programa.<br>
Más adelante, usaré la función ldiv(num,denom) en lugar de las de la clase Division, GetCociente y GetResto.<br>
La última debería ser con una interfaz gráfica.<br>
Ni que decir tiene que agradeceré cualquier crítica o referencia para mejorar, tanto el código como los conceptos que he manejado.<br>
<br>
Os pego los tres archivos y el resultado del ejemplo.<br>
Como lo he hecho en ubuntu, el comando de compilación ha sido:<br>
g++ -odividete_v3 dividete_v3.cpp division_v3.cpp<br>
<br>
[Archivo division_v3.h]<br>
/* Clase Division<br>
* Versión 3<br>
* Declaración<br>
*/<br>
#ifndef DIVISION_V3_H<br>
#define DIVISION_V3_H<br>
<br>
#define MAX_CIFRAS 9<br>
#define NUM_FILAS 15<br>
#define NUM_COLUMNAS 20<br>
<br>
class Division<br>
{<br>
public:<br>
Division(long numerador, long denominador);<br>
long BajaLaCifraSiguiente();<br>
long GetCociente(long num);<br>
long GetResto(long num);<br>
void DibujaLaDivision(); // Dibuja el enunciado de la división en la hoja<br>
void Pinta(); // Muestra la hoja con la división completa<br>
int GetNumeroDeCifras(long numero);<br>
private:<br>
// miembros<br>
// Son char para simular la colocación de cada cifra en su posición<br>
char m_dividendoChar[MAX_CIFRAS];<br>
long m_divisor;<br>
char m_divisorChar[MAX_CIFRAS];<br>
char m_cocienteChar[MAX_CIFRAS];<br>
char m_restoChar[MAX_CIFRAS];<br>
int m_cifra;<br>
int m_fila;<br>
char m_cuadricula[NUM_FILAS][NUM_COLUMNAS]; // Simula una página cuadriculada<br>
};<br>
<br>
#endif // DIVISION_V3_H<br>
<br>
<br>
[Archivo division_v3.cpp]<br>
/* Clase Division<br>
* Versión 3<br>
* Definición<br>
*/<br>
#include "division_v3.h"<br>
<br>
#include <cstdio><br>
#include <cstdlib><br>
#include <cstring><br>
#include <iostream><br>
#include <math.h><br>
<br>
using namespace std;<br>
<br>
#undef verbose<br>
<br>
Division::Division(long numerador, long denominador)<br>
{<br>
for(int i = 0; i < MAX_CIFRAS; i++)<br>
{<br>
m_dividendoChar[i] = ' ';<br>
m_divisorChar[i] = ' ';<br>
m_cocienteChar[i] = ' ';<br>
m_restoChar[i] = ' ';<br>
}<br>
m_dividendoChar[MAX_CIFRAS] = 0;<br>
m_divisorChar[MAX_CIFRAS] = 0;<br>
m_cocienteChar[MAX_CIFRAS] = 0;<br>
m_restoChar[MAX_CIFRAS] = 0;<br>
m_divisor = denominador;<br>
sprintf(m_dividendoChar, "%ld", numerador);<br>
sprintf(m_divisorChar, "%ld", denominador);<br>
m_cifra = 0;<br>
m_fila = 0;<br>
for(int f = 0; f < NUM_FILAS; f++)<br>
for(int c = 0; c < NUM_COLUMNAS; c++)<br>
m_cuadricula[f][c] = ' ';<br>
}<br>
<br>
long Division::BajaLaCifraSiguiente()<br>
{<br>
char c[MAX_CIFRAS];<br>
sprintf(c, "%c", m_dividendoChar[m_cifra]);<br>
#ifdef verbose<br>
cout << "\nBajaLaCifraSiguiente obtiene '" << m_dividendoChar[m_cifra] << "'";<br>
#endif<br>
#ifdef verbose<br>
cout << "\nBajaLaCifraSiguiente añade '" << c << "'";<br>
#endif<br>
strncat(m_restoChar, c, 1);<br>
#ifdef verbose<br>
cout << "\nBajaLaCifraSiguiente y queda '" << m_restoChar << "'";<br>
#endif<br>
long restoTemp = atol(m_restoChar);<br>
#ifdef verbose<br>
cout << "\nBajaLaCifraSiguiente convertida a long " << restoTemp;<br>
#endif<br>
m_fila++;<br>
#ifdef verbose<br>
cout << "\nBajaLaCifraSiguiente va a la fila " << m_fila;<br>
#endif<br>
for(int col = 0; col <= m_cifra; col++)<br>
m_cuadricula[m_fila][col] = m_restoChar[col];<br>
#ifdef verbose<br>
Pinta();<br>
#endif<br>
return restoTemp;<br>
}<br>
<br>
long Division::GetCociente(long numerador)<br>
{<br>
long cocienteTemporal = numerador / m_divisor;<br>
#ifdef verbose<br>
cout << '\n' << numerador << " entre " << m_divisor << " es " << cocienteTemporal;<br>
#endif<br>
char s[MAX_CIFRAS];<br>
sprintf(s, "%ld", cocienteTemporal);<br>
strncat(m_cocienteChar, s, 1);<br>
#ifdef verbose<br>
cout << "\nCociente combinado:" << m_cocienteChar;<br>
#endif<br>
long cociente = atol(m_cocienteChar);<br>
return cociente;<br>
}<br>
<br>
long Division::GetResto(long numerador)<br>
{<br>
long resto = numerador % m_divisor;<br>
int cifrasResto = GetNumeroDeCifras(resto);<br>
#ifdef verbose<br>
cout << "\nEstoy en la cifra " << m_cifra;<br>
#endif<br>
sprintf(m_restoChar, "%*ld", m_cifra + 1, resto);<br>
#ifdef verbose<br>
cout << "\nrestoChar queda: '" << m_restoChar << "'";<br>
#endif<br>
m_cifra++;<br>
return resto;<br>
}<br>
<br>
void Division::DibujaLaDivision()<br>
{<br>
#ifdef verbose<br>
cout << "Dibuja divisorChar:" << m_divisorChar;<br>
#endif<br>
int posicion = NUM_COLUMNAS - MAX_CIFRAS;<br>
for(int c = 0; c < posicion; c++)<br>
if(m_dividendoChar[c] >= '0')<br>
m_cuadricula[0][c] = m_dividendoChar[c];<br>
m_cuadricula[0][posicion] = '|';<br>
for(int c = 0; c < posicion; c++)<br>
if(m_divisorChar[c] >= '0')<br>
m_cuadricula[0][posicion+2+c] = m_divisorChar[c];<br>
m_cuadricula[1][posicion] = 'L';<br>
for(int c = posicion+1; c < NUM_COLUMNAS; c++)<br>
m_cuadricula[1][c] = '_';<br>
m_fila = 1;<br>
}<br>
<br>
void Division::Pinta()<br>
{<br>
int posicion = 2 + (NUM_COLUMNAS - MAX_CIFRAS);<br>
for(int c = 0; c < MAX_CIFRAS; c++)<br>
if( (m_cocienteChar[c] >= '0') && (m_cocienteChar[c] <='9') )<br>
m_cuadricula[2][c + posicion] = m_cocienteChar[c];<br>
<br>
for(int f = 0; f < NUM_FILAS; f++)<br>
{<br>
cout << endl;<br>
for(int c = 0; c < NUM_COLUMNAS; c++)<br>
cout << m_cuadricula[f][c];<br>
}<br>
cout << endl << endl;<br>
}<br>
<br>
int Division::GetNumeroDeCifras(long numero)<br>
{<br>
int cifras = int(log10(numero)) + 1;<br>
/* Gracias Steven<br>
* Definitivamente, las matemáticas no son mi fuerte.<br>
*/<br>
return cifras;<br>
}<br>
<br>
<br>
<br>
[Archivo dividete_v3.cpp]<br>
/* Proyecto: dividete. Comprobar una división en modo texto.<br>
* Versión 3<br>
* Autor : Marcelino Gisbert<br>
* Objetivo: El alumno introducirá el dividendo y el divisor.<br>
* La aplicación calculará el número de cifras del dividendo y las del denominador.<br>
* Se repetirán tantas divisiones enteras con las cifras del denominador<br>
* para ir construyendo la división tal y como se haría a mano.<br>
* Se mostrará en una rejilla a modo de papel cuadriculado.<br>
* TODO<br>
* Debo resolver el inconveniente de introducir letras en lugar de números.<br>
* Para probar, me ceñiré al ejemplo.<br>
* En la versión 3, probaré el formateo de la entrada.<br>
* También se implementará una versión que acepte las cantidades como parámetros<br>
* de main.<br>
*<br>
* Ejemplo:<br>
* Dado el dividendo: 35437<br>
* Y el divisor.....: 283<br>
* El proceso sería :<br>
* Se escribe el dividendo (hasta 19 cifras)<br>
* A continuación, el divisor tras su "separador"<br>
* En la siguiente línea cerramos el operador de división.<br>
* Quedaría así:<br>
* 35473 | 283<br>
* L____________________<br>
<br>
* Obtener el número de cifras de 35437: 5<br>
* Se baja una cifra hasta que se pueda dividir.<br>
* Primero el 3<br>
* Se divide y se obtiene el resto de la división entera: 3<br>
* Se baja la cifra siguiente: el 5.<br>
* Se añade al resto anterior: 35.<br>
* Se divide y se obtiene el resto: 35.<br>
* Se baja la cifra siguiente: el 4.<br>
* Se añade al resto anterior: 354.<br>
* Se divide y se obtiene cociente (1) y el resto (71).<br>
* Se baja la cifra siguiente: el 3.<br>
* Se añade al resto anterior: 713.<br>
* Se divide y se obtiene el cociente (2) y el resto (147).<br>
* Se baja la cifra siguiente: el 7.<br>
* Se añade al resto anterior: 1477.<br>
* Se divide y se obtiene el cociente (5) y el resto (62).<br>
* Acabaron las cifras del dividendo.<br>
* El resultado se ve escalonado: cociente 125, resto 62.<br>
*/<br>
<br>
#include <iostream><br>
<br>
#include "division_v3.h"<br>
<br>
using namespace std;<br>
<br>
void MuestraAyuda()<br>
{<br>
cout << "\n\nHijo, comprueba tu división." << endl;<br>
cout << "Lo ha hecho papá para que ganes tiempo en tus deberes." << endl;<br>
cout << "No para que hagas trampa ;-)" << endl;<br>
cout << "Funciona así:" << endl;<br>
cout << "Primero te pediré el dividendo." << endl;<br>
cout << "\tDebes escribir un número mayor o igual a 0." << endl;<br>
cout << "\tSi escribes un cero, se termina." << endl;<br>
cout << "Después te pediré el divisor." << endl;<br>
cout << "Entonces iré escribiendo la división como lo harías tú en papel." << endl;<br>
cout << "Bueno, más o menos :-)" << endl;<br>
cout << "Vale. ¡Vamos allá!" << endl;<br>
}<br>
<br>
long GetDividendo()<br>
{<br>
long numerador = 0;<br>
cout << "Dame el dividendo (Recuerda que 0 es para terminar)" << endl;<br>
cin >> numerador;<br>
return(numerador);<br>
}<br>
<br>
long GetDivisor()<br>
{<br>
long denominador = 0;<br>
cout << "Dame el divisor (no puede ser 0)" << endl;<br>
cin >> denominador;<br>
return(denominador);<br>
<span class="">}<br>
<br>
int main()<br>
{<br>
MuestraAyuda();<br>
long numerador = 1, denominador = 1;<br>
while( numerador = GetDividendo() )<br>
{<br>
</span> if(numerador)<br>
<span class=""> {<br>
if( denominador = GetDivisor() )<br>
{<br>
</span> Division *pagina = new Division(numerador, denominador);<br>
pagina->DibujaLaDivision();<br>
#ifdef verbose<br>
pagina->Pinta();<br>
#endif<br>
int cifrasNumerador = pagina->GetNumeroDeCifras(numerador);<br>
for(int cifra = 0; cifra < cifrasNumerador; cifra++)<br>
{<br>
long numSiguiente = pagina->BajaLaCifraSiguiente();<br>
long cocParcial = pagina->GetCociente(numSiguiente);<br>
long resParcial = pagina->GetResto(numSiguiente);<br>
}<br>
// Al bajar la cifra siguiente a la última es<br>
// cuando se coloca en la cuadrícula.<br>
pagina->BajaLaCifraSiguiente();<br>
pagina->Pinta();<br>
delete pagina;<br>
}<br>
}<br>
cout << endl ;<br>
}<br>
return 0;<br>
}<br>
<br>
<br>
[Resultado]<br>
marcelinux@HP:~/ds$ g++ -odividete_v3 dividete_v3.cpp division_v3.cpp<br>
marcelinux@HP:~/ds$ ./dividete_v3<br>
<br>
<br>
Hijo, comprueba tu división.<br>
Lo ha hecho papá para que ganes tiempo en tus deberes.<br>
No para que hagas trampa ;-)<br>
Funciona así:<br>
Primero te pediré el dividendo.<br>
Debes escribir un número mayor o igual a 0.<br>
Si escribes un cero, se termina.<br>
Después te pediré el divisor.<br>
Entonces iré escribiendo la división como lo harías tú en papel.<br>
Bueno, más o menos :-)<br>
Vale. ¡Vamos allá!<br>
Dame el dividendo (Recuerda que 0 es para terminar)<br>
35437<br>
Dame el divisor (no puede ser 0)<br>
283<br>
<br>
35437 | 283<br>
L________<br>
3 00125<br>
35<br>
354<br>
713<br>
1477<br>
62<br>
<div class="HOEnZb"><div class="h5"><br>
__________________________________________________________________<br>
Programador, ávido de conocimiento y algo testarudo.<br>
Gracias a todos los que comparten. Espero poder devolver el favor.<br>
_______________________________________________<br>
Lista de correo Cconclase <a href="mailto:Cconclase@listas.conclase.net">Cconclase@listas.conclase.net</a><br>
<a href="http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net" target="_blank">http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net</a><br>
Bajas: <a href="http://listas.conclase.net/index.php?gid=2&mnu=FAQ" target="_blank">http://listas.conclase.net/index.php?gid=2&mnu=FAQ</a><br>
</div></div></blockquote></div><br></div>