<div dir="ltr">Hola Marcelino,<br><div class="gmail_extra"><br><div class="gmail_quote">2014-09-25 10:49 GMT-04:00 marcelinux <span dir="ltr"><<a href="mailto:marcelinator@gmail.com" target="_blank">marcelinator@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hola amigos.<br>
Espero que no se moleste nadie por tratarle de amigo sin conocernos tanto, pero, para mí, una persona que comparte su conocimiento y sus dudas, me merece el trato de amigo.<br></blockquote><div><br></div><div>Personalmente, no me molesta.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Al tema.<br>
Soy programador de otros lenguajes y estoy empezando con c y c++.<br>
He encontrado un programa en c que resuelve una división entera mostrando el cociente y el resto.<br>
Lo voy a usar para comprobar las divisiones de mi hijo en el cole.<br>
Pero, yendo más allá, lo he "convertido" en c++, mostrando cada iteración.<br>
Ya sabes, tomo la primera cifra, divido, calculo el resto, bajo la cifra siguiente, etc.<br>
La visualización es algo pobre porque, habiendo librerías gráficas y semigráficas (wxWidgets o nCurses), iré mejorando su aspecto.<br>
Os pego ambos programas.<br>
PD: Los he realizado en fuentes completos (sin cabeceras) para poder consultarlos con AvPag y RePag.<br>
Se admite cualquier comentario constructivo<br>
<br></blockquote><div><br></div><div>Genial. Te comento mientras veo el código fuente.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
division_con_resto.c<br>
[code]#include <stdio.h><br>
main(){<br>
        int numerador=1,denominador;<br>
        while(numerador){<br>
                printf("Dame el numerador (0=fin)\n");<br>
                scanf("%d",&numerador);<br>
                if(numerador){<br></blockquote><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                        printf("\nDame el denominador\n");<br>
                        scanf("%d",&denominador);<br>
                        int vueltas=0;<br>
                        while(numerador>=denominador){<br>
                                numerador=numerador-denominador;<br></blockquote><div><br></div><div>Acostúmbrate a usar los operadores de "operación y asignación"; esto es,<br><br>numerador -= denominador;<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                vueltas++;<br>
                        }<br></blockquote><div><br></div><div>Como no haces otra cosa que obtener el cociente y el resto en este bucle, sugiero dividir entre enteros directamente - sin la necesidad de un bucle. Esto es,<br><br></div><div>cociente = numerador / denominador;<br></div><div>resto = numerador % denominador;</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                        printf("Cociente: %d\n",vueltas);<br>
                        printf("Resto: %d\n", numerador);<br>
                }<br>
        }<br></blockquote><div><br></div><div>Debes retornar un entero. Si no, entonces indica 'void' para 'main()'.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
}[/code]<br>
<br></blockquote><div><br></div><div>Como una mejora, podemos eliminar la sentencia 'if' en el primer bucle si reorganizamos las sentencias y el bucle para repetir otro patrón de sentencias. Como un bucle ya "contiene" una condición, podemos combinar ambas sentencias: 'if' y 'while' en un solo bucle. Esto es,<br><br></div>printf( "Dame el numerador (0=fin)\n" );<br><div>scanf( "%d", &numerador );<br><br></div>while( numerador )<br><div>{<br>  printf( "\nDame el denominador\n" );<br>  ...<br>  printf( "Dame el numerador (0=fin)\n" );<br>  scanf( "%d", &numerador );<br>}<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
dividete.cpp<br>
<br></blockquote><div><br></div><div>[CORTE]<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
#include <cstdlib><br>
#include <string><br>
#include <iostream><br>
#include <iomanip><br>
#include <sstream><br>
<br>
//#define vervose<br>
<br>
int cifrasNumerador;<br>
char linea[21] = "                    ";<br>
const char rayas[11] = "__________";<br>
int posicionResto = 1, posicionCociente = 4;<br></blockquote><div><br></div><div>No es nada recomendable usar variables globales. Sin embargo, no hay problema si definimos constantes globales.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
using namespace std;<br>
<br></blockquote><div><br></div><div>[CORTE]<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
int GetNumeroDeCifras(long numero){<br></blockquote><div><br></div><div>No es necesario hacer estas conversiones. Podemos usar matemáticas para determinar la cantidad de dígitos decimales; esto es,<br><br></div><div>return int(log10(numero)) + 1;</div><div><br></div><div>[CORTE]<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
string BajaLaCifraSiguiente(string dividendoStr, string restoStr, int cifra){<br></blockquote><div><br></div><div>Al pasar objetos, los cuales no tienes intención de modificar, procura pasarlos por referencia (a objetos constantes) en lugar de por copia; o sea,<br><br>string BajaLaCifraSiguiente( const string &dividendoStr, const string &restoStr, int cifra )<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
        #ifdef vervose<br>
                cout << "BajaLaCifraSiguiente\tRecibe dividendoChar:" << dividendoStr << ", resto:" << restoStr << " y cifra:" << cifra << endl;<br>
        #endif<br>
        char digito;<br>
        digito = dividendoStr[cifra];<br>
        #ifdef vervose<br>
                cout << "Dígito " << digito << " en la cifra " << cifra << endl;<br>
        #endif<br>
        int posicion;<br>
        posicion = restoStr.length();<br>
        #ifdef vervose<br>
                cout << "Posición donde se inserta en el resto: " << posicion << endl;<br>
        #endif<br>
        char *dividendoParcial = new char[posicion+1];<br>
        int i;<br>
        for(i = 0; i <= posicion; i++){<br></blockquote><div><br></div><div>Tenemos un error al llegar a la última iteración, porque usamos 'i' como índice para cadenas de diferentes cantidades: 'restoStr()' tiene una cantidad menor que 'dividendoParcial', la cual tiene un carácter más. El problema está en acceder al elemento de índice, 'posicion', del objeto, 'restoStr()'.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                #ifdef vervose<br>
                        cout << "i = " << i;<br>
                        cout << "\trestoStr[" << i << "] = " << restoStr[i] << endl;<br>
                #endif<br>
                dividendoParcial[i] = restoStr[i];<br>
                #ifdef vervose<br>
                        cout << "dividendoParcial[" << i << "] = " << dividendoParcial[i] << endl;<br>
                #endif<br>
        }<br>
        dividendoParcial[posicion] = digito;<br>
<br></blockquote><div><br></div><div>Como estás construyendo una cadena para 'dividendoParcial', debes indicar el final de tal cadena asignando el carácter nulo. Esto significa que deberías hacer esto,<br><br>dividendoParcial[posicion] = 0;<br><br></div><div>Por lo tanto, o bien necesitas un carácter de más, o bien la cadena termina en el índice 'posicion-1' para que puedas asignar el carácter nulo en el índice: 'posicion'.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
        #ifdef vervose<br>
                cout << "BajaLaCifraSiguiente\tDevuelve " << dividendoParcial << endl;<br>
        #endif<br>
        return(dividendoParcial);<br></blockquote><div><br></div><div>Esto supondrá un grave problema de fuga de memoria, porque no habrá forma de liberar la memoria que adjudicaste dinámicamente con 'new[]'. Deberías hacer esto:<br><br></div><div>string resultado( dividendoParcial );<br>delete[] dividendoParcial;<br><br></div><div>return resultado;  // No necesitas paréntesis<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
}<br>
<br></blockquote><div><br></div><div>Como al final necesitas un objeto de la clase 'string', sugiero crear tal objeto dinámico en lugar de crear un array dinámico.<br></div><div><br></div><div>Por último, creo que no necesitas usar cadenas de caracteres. Puedes usar matemáticas para conseguir lo que quieres y así no tienes que estar andando con conversiones entre cadenas y enteros, hasta el momento de necesitarlas: cuando hay que mostrar los resultados a la pantalla.<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
long int Divide(long dividendo, long divisor){<br>
        #ifdef vervose<br>
                cout << "Divide\tRecibe dividendo:" << dividendo << " y divisor:" << divisor << endl;<br>
        #endif<br>
        long res = dividendo;<br>
        if(dividendo > divisor){<br>
                long coc = GetCociente(dividendo, divisor);<br>
                res = GetResto(dividendo, divisor);<br>
<br>
                posicionCociente++;<br>
                cout << "\n" << dividendo;// << "    ";<br>
                cout.write(linea, posicionCociente);<br>
                cout << coc << endl;<br>
                cout << res << endl;<br>
        }<br>
        #ifdef vervose<br>
                cout << "Divide\tDevuelve resto:" << res << endl;<br>
        #endif<br>
        return(res);<br>
}<br>
<br>
int main(){<br>
        MuestraAyuda();<br>
        long numerador = 1, denominador = 1;<br>
        while( numerador = GetDividendo() ){<br>
                int r;<br>
                if(numerador){<br></blockquote><div><br></div><div>Aquí puedes intentar combinar 'while' y esta 'if' en un solo 'while', como hicimos antes.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                        if( denominador = GetDivisor() ){<br>
                                cifrasNumerador = GetNumeroDeCifras(numerador);<br>
                                DibujaLaDivision(numerador, denominador);<br>
<br>
                                string dividendoStr = NumToString(numerador);<br>
<br>
                                string restoStr;<br>
                                string numeradorParcialStr;<br>
                                numeradorParcialStr = dividendoStr[0];<br>
                                long restoParcial = strtol(numeradorParcialStr.c_str(), NULL, 0);<br></blockquote><div><br></div><div>No veo que sea necesario esta conversión, porque a estas alturas 'numeradorParcialStr' contiene un solo carácter. Puedes hacer la conversión directamente; por ejemplo,<br><br></div><div>long restoParcial = numeradorParcialStr[0] - '0';<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                int cifra;<br>
                                for(cifra = 1; cifra < cifrasNumerador; cifra++){<br>
                                        restoStr = NumToString(restoParcial);<br>
                                        numeradorParcialStr = BajaLaCifraSiguiente(dividendoStr, restoStr, cifra);<br></blockquote><div><br></div><div>Como usas 'numeradorParcialStr' para luego convertir su cadena a un entero, ¿por qué no trabajar siempre con enteros? Así te libras de hacer tantas conversiones.<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                                        long numeradorParcialLong = strtol(numeradorParcialStr.c_str(), NULL, 0);<br>
                                        restoParcial = Divide(numeradorParcialLong, denominador);<br>
                                        r = GetNumeroDeCifras(restoParcial);<br>
                                }<br>
                        }<br></blockquote><div><br><br></div><div>Espero que todo esto te oriente.<br></div><div><br></div><div>Steven<br><br></div></div></div></div>