Un programita en C :D

Weno, este es un programa que hice hace bastante tiempo, y que me propuse mejorar (he aumentado un poco lo que tenia). ¿que por que lo pongo aqui? jejeje, pues por que lo que os mando es el codigo para ver si encontrais algun bug (espero que encontreis menos que en el IE xD), o si me podeis decir alguna cosa para añadirle, modificarle etc.....
Weno, pues a ver si me ayudais a conseguir un programilla en condiciones que me ayude en este trimestre ;)

Saludos y Gracias!

PD: joder... no me dejaba subir el *.cpp

Edito: No se por que al principio no me daba ningun error, pero ahora no me rula bien la primera opcion. ¿que puedo haber tokado?
Edito: Solucionado!

Adjuntos

Yo no se mucho de C, pero creo que el menu del principio lo podrias hacer con un "do - while" en vez de con if
do{
printf("\n Opciones:\n\n 1.Ecuacion de primer grado\n 2.Ecuacion de segundo grado\n 3.Salir");
printf("\nOpcion: ");
scanf("%d",&opcion);
fflush(stdin);
if(opcion==1)
{
e_1();
}
if(opcion==2)
{
clrscr ();
printf("Opciones:\n 1.Ecuacion completa\n 2.Ecuacion sin termino independiente\n 3.Ecuacion con termino independiente");
scanf("%d",&opcion2);
if(opcion2==1)
{
e_2c();
}
if(opcion2==2)
{
e_2si();
}
if(opcion2==3)
{
e_2ci();
}
}
}while(opcion!=3);


Si que es ta el do - while, pero para conseguir que seleccione las otras opciones pongo el if. es a eso a lo que te refieres? o a poner cada opcion con un do - while? no lo acabo de entender....
Hombre, pues por: arreglar, comentar y limpiar el código no iba a pasar nada ;) Es lo mínimo si quieres que lo leamos jeje.

Es mejor hacer 3 printf a hacer un printf con tres \n. por pura claridad :)

No estaría nada mal que cumpliera estándares... conio.h por ejemplo... no he conseguido compilarlo en OSX, a ver si arreglándolo un poco...


Salu2.Ferdy
Holaaaa...

Uhmmm, interesante propuesta, y como tengo 15 minutos para desayunar vamos a comentar un poco:

void main ()
{
int opcion;
int opcion2;
void e_1();
void e_2c();
void e_2si();
void e_2ci();
void e_bi();

uhhhhmmmmmmmmm.... me duele un poco a la vista, no es incorrecto que yo recuerde, pero, este... como que no. Las cabeceras de funciones siempre es mejor ponerlas fuera. Es más, si es un programa corto, puedes poner las funciones enteras encima del main(), y no hará falta que declares cabeceras.

Otro tema es la estandarización, parece mentira pero las cosas van mejor si se siguen las normas... y que mejores normas que las ANSI para estos casos: en lugar de void main(), pondría int main(int argc, char** argv). El motivo es sencillo: por lo general, el sistema operativo o un programa que llame al tuyo espera una respuesta al finalizar el programa... por ejemplo, si devuelves 0 es que no hay problemas (por ejemplo, ya que suele depender del programa). Si haces este cambio de cabecera, al final debes retornar algo... si no sabes que retornar "return 0;" es una buena opción. Los dos parámetros que le pasas: el entero argc es el número de parámetros externos que recibe el programa, y argv un array que contiene los parámetros pasados, siendo 0 el nombre del mismo, 1 el primer parámetros, 2 el segundo...

En lugar de esperar un "entero" en la linea scanf("%d",&opcion);, esperaría un carácter scanf("%c",&opcion);. De esta forma el programa no petará si le insertas una 'q' en lugar de un '1'. para ello solo has de cambiar la '%d', por '%c' y "int opcion;" por "char opcion;". Otra cambio, o cambios, que deberás hacer es donde pongas una igualdad del estilo (opcion == 1), ahroa deberás poner (opcion == '1') (sea 1 o 3 o a o B, o J...), ya que no es lo mismo comparar valores enteros que valores de carácter.

En lugar de hacer tantos if, que afean mucho el código y pueden llegar a perder un poco, haría un switch. La sintaxis de este es la siguiente:
switch(opcion)
{
case '1':
printf("Como me gusta comer chipirones\n");
break;
case '2':
[...................]
break;

default:
printf("Opción incorrecta, calamar!\n");
}


clrscr() no es standard. Que yo recuerde solo exíste en la conio.h de Borland. Hay implementaciones "chungas" de la conio.h para otros SO, pero no se usan porque, a parte de desfasadas, son algo sucias y lentas. Es preferible remarcar cada linea dejando varias \n\n como separadores, que muchas veces limpiar la pantalla.

No uses con descaro los \n para separar una cadena dentro de un mismo printf... no es nada claro, a parte que en un programa de estas características no necesita optimizaciones de este tipo (tu solo harias una llamada a función, en lugar de tres... pero... no es el Doom 3...).

Sigue una metodología en la indentación, sea cual sea, pero síguela: si quieres poner el '{' justo después de un if, un while, una función... hazlo siempre... o si lo quieres poner debajo, pero aclarate! que cuesta de seguir.

if(pakito='a')
{

}

ó

if(pakito='a'){

}

Es a cuestión de gustos... mucha gente sigue la primera (como yo) porque es más rápido de ver cuales te faltan por cerrar. Otras personas prefieren la segunda, porque suele ser la indentación usada en programas comunitários y por software como Anjuta. Esto en el fondo da un poquitín igual, siempre y cuando os pongais deacuerdo, o al menos te pongas deacuerdo tu.

Comenta el coooooooodigo... esto que parece una tontería salva cabezas en el último momento. Es más, sabes que realmente no te dejarían liberar código bajo la GPL (o cualquier otra libre) si no está decentemente comentado? aunque puedas, no te mirarán con buenos ojos. Liberar el código sirve para que todos aprendamos... si el código es demasiado ofuscado y sin comentarios, nadie aprende.

No se me ocurre nada más... voy a acabar de desayunar que el ColaCado (como Bacalado) se me está enfriando, que en mi casa hace mucho frio... tanto que me he estado portando muy mal para ver si los reyes me traian carbón... me han traido unos troncho calcetines y unos gallumbos que me vienen pequeños... no, si tendrán razón los republicanos... pero tampoco me trajo nada el gordo ese.

Saludos!!!!
Vamos por partes:

No estaría nada mal que cumpliera estándares... conio.h por ejemplo... no he conseguido compilarlo en OSX, a ver si arreglándolo un poco...


Problema resuelto, ya no esta el clrscr. Lo he sustituido por una funcion que he añadido al programa:
void limpia_pantalla()
{
printf("\n\n\n\n\n\n\n\n\n\n\nn\n\n\n\n");
}
Mejor? Creo que era la unica que usaba conio.h era esa, pero luego pruebo a compilarle en otro SO

uhhhhmmmmmmmmm.... me duele un poco a la vista, no es incorrecto que yo recuerde, pero, este... como que no. Las cabeceras de funciones siempre es mejor ponerlas fuera. Es más, si es un programa corto, puedes poner las funciones enteras encima del main(), y no hará falta que declares cabeceras.


Esto no lo acabo de entender (soy muy novato en la programacion, tan solo llevo desde verano programando y bastante que hago que solo tengo 15 años :D), no se si he entendido bien, ¿si pongo las funciones arriba (void e_1, void e_2si, etc) no me hace falta poner en main los void?

Mas
if(pakito='a')
{

}

ó

if(pakito='a'){

}


Lo de los if.... emmmmm ¿solo he usado del primer tipo?¿o esque te refieres al do - while?

Lo de los switch [looco] no me habia dado cuenta jeje, pero de todas formas creo que hay un if que no puedo sustituir por el case porque ¿como pongo entonces esto?

if((oper1=='+')&&(oper2=='+'))


Al ir limitado por dos operadores me pierdo con el case.......

Comenta el coooooooodigo... esto que parece una tontería salva cabezas en el último momento. Es más, sabes que realmente no te dejarían liberar código bajo la GPL (o cualquier otra libre) si no está decentemente comentado? aunque puedas, no te mirarán con buenos ojos. Liberar el código sirve para que todos aprendamos... si el código es demasiado ofuscado y sin comentarios, nadie aprende.




Dicho y hecho! [oki]

PD:a mi tb me han traido unos gallumbos, aunque no se si me valdran xD

Saludos y thnx!
Lo de los switch...
Obviamente, no todo lo podrás hacer con switchs, pero lo que es cuestión de menús típicos "1-2-3" o "a-b.......-z" o lo que sea, si.


...funciones arriba (void e_1, void e_2si, etc)...

Si las funciones en lugar de escribirlas una vez acabado el main(), las pones por encima, no hace falta poner las cabeceras dentro del main (de todas formas, auque las pongas al final.... no pongas las cabeceras dentro del main...).

void limpia_pantalla()
:-| no recuerdo ninguna función para limpiar la pantalla... antes usaba ncurses... ahora ni me acuerdo de que función era, pero bueno, te sirve :P

ciao
Para limpiar la pantalla puedes usar el siguiente codigo:

#include <stdlib.h>
#include <stdio.h>

void clr();

int main()
{
    clr();

    return 0;
}


void clr()
{
   system("clear");
}




Un saludo [oki]
Escrito originalmente por Zeenek
Yo no se mucho de C, pero creo que el menu del principio lo podrias hacer con un "do - while" en vez de con if


Queria decir con un switch (case) ; )
esque ayer llegue un poco ciego a casa y pasa lo que pasa, jurjur
system("clear");
Mucho me temo que esto funcionará bien poco en algunos SO... solo en los Unix y familia.

Pero bueno, también puedes usar TIPEX :D
Aportare a este hilo un consejo nada mas :) porque de C estoy cansado en estas navidades ( me las pase casi enteras liado con el C ) pero la verdad que lo mejor que puedes hacer al mismo tiempo que programas C es buscarte Doc de Metodologia, parece una tonteria pero es muy muy necesaria cuando te dedicas a hacer Soft que contenga mucho codigo, es decir el buen tabulado, utilizar separaciones con comentarios para separar los pasos por ejemplo, el limpiar mucho el codigo, la forma mejor para comentar que hace cada parte de ese Soft ( que para ti es facil porque la pensaste en ese momento, pero para ti posteriormente o alguien que quiera leerla no sabe exactamente porque esta hay ) etc etc ... Cuando domines bien la metodologia todo te saldra mucho mas rapido, mas facil de buscar los errores y mas profesional desdeluego :)


Un saludo
Pues una vez tomado todo lo que me dijisteis lo he actualizado. Os adjunto la nueva version.
Lo que peor llevo es lo de comentarlo, por que lo de la lengua no es lo mio [+risas]
¿entonces me recomendais que me lea tutoriales de Metodologia? Ahora busco alguno a ver k sale

PD:
pero la verdad que lo mejor que puedes hacer al mismo tiempo que programas C es buscarte Doc de Metodologia


O_O no!!!!! doc no!!!!! swx xD

Saludos!

EDITO: me he dado cuenta de un par de fallos que no se de donde vienen.
1. al iniciar el programa me salta un pitido , ¿soy el unico?
2. cuando eligo la opcion c (salir) al final aparece opcion incorrecta
soluciones plis?
Y se me olvida el adjunto.....

Adjuntos

no he visto el código pq no tengo mucho tiempo, pero

if(pakito='a')

es incorrecto

sería

if(pakito=='a')


Ya que si pones = lo que haces es asignar el valor 'a' a la variable pakito.

Saludines [poraki]
Sobre lo de Doc me referia a Documentacion xD esta claro que es mejor el formato de OpenOffice ( o por lo menos es el que yo utilizo casi siempre ) y sobre lo de buscar documentacion de metodologia puede que te encuentre algo en unos dias solo tengo que buscar en mis apuntes :P y conforme la tenga te la paso :)


Venga un saludo
lo del pitido...

en la linea 216 tienes
printf("Ecuacionador -> By \-\adEs");

si pones \a en un printf lo que hace es escribir el caracter alarma (en algunos S.O se interpreta como un "pito", separa la barra de la 'a' y soliconado..


sobre lo de opcion incorrecta...

Tienes éste switch.
switch(opcion)//para no liar tanto con los if (gracias rurouni)
{
case 'a':
e_1();
break;
case 'b':
.....
.....

default:
printf("Opcion incorrecta!\n");
}
}while(opcion!='c');

Si pones un default, cuando entres y pulses 'c' te va a salir lo de opcion incorrecta, aunque luyego salgas del switch y te encuentres con el while, puedes hacer dos cosas.

-Reorganizar el código para que no haga eso...

int saliendo=0;

do{
switch(opcion)
{
case 'c' : saliendo=1;
break;
}
}
while(saliendo!=1)

-o poinendo un case para la letra 'c', que simplemente no haga nada, así no pasará por el default.

Saludos.
o del pitido...

en la linea 216 tienes
printf("Ecuacionador -> By \-\adEs");


[+risas] no sabia que mi nick diese un error [+risas] , ahora lo cambio.

En lo del switch un conmutador que se active al elegir c ¿no?

Muchas Gracias!!!
Ejem...

printf("Escribe ax:\t");
scanf("%d",&ax);
fflush(stdin);
printf("\nEscribe el operador:\t");
scanf("%c",&operador);
fflush(stdin);
printf("\nEscribe b:\t");
scanf("%d",&b);
fflush(stdin);
printf("\nEscribe el total:\t");
scanf("%d",&c);
fflush(stdin);


creo que con que hagas el fflush una vez al final de cada funcion te sobra :P


Para solucional lo del error en el default puedes crear un asi saldra igualmente y no te dara el error en el default :P
Sobre lo de tu nick, creo recordar que si pones \-\\adEs, es decir \\a, saldra por pantalla \a y no hara el pitido, es otra forma mas elegante de que no salga el pitido sin tener que poner un espacio
Muchas gracia por lo del nick Zeenek [oki] asi ya no tengo que ponerlo con h :D

Sobre lo del fflush..... siento comunicarte que no..... tenerlo sin ninguno es lo primero que probe y si me salto uno, sea el que sea me salta al siguiente scanf. Con los caracteres lo entiendo pero con los int no....

Saludos!
Y si en vez de usar scanf() usas getchar()? No es necesario que el usuario pulse el retorno de carro, solo devolvera el primer carácter que pulses. Yo lo veo mas limpio.

Saludos
Jeje, yo creia que getchar() era solo para cadena, y como lo que estaba reconociendo eran caracteres [+risas]
Luego lo actualizo y modifico el ultimo adjunto

Otra vez: Muchas gracias! [oki]
Getchar es para un solo caracter, para cadenas es el gets() pero al verdad si utilizaras para cadenas el gets el gcc te daria una advertencia :P

Un saludo
getchar no funciona muy bien en linux (compilador), a mi me ha dado bastantes problemas, sobretodo no pongas su equivalente getche, que esta en la libreria conio.h y no rula en linux.
Para que gecthar funcione bien, ya que a mi no me iba pon lo siguiente:

ch = getchar();
while (getchar() != '\n');


donde ch, es la variable
1. Getche no lo puedo usar por que quite la libreria conio.h ya que no tiraba en algunos S.O.
2. Con lo de getchar me he hecho un lio de flipar...... he leido la informacion de mi compilador y no entiendo nada, ¿para que coño pone un int?
int main(void)
{
int c;

while ((c = getchar()) != '\n')
printf("%c", c);

return 0;
}

¿Se supone que trasforma el en int a char? por que despues lo que lee es un caracter, y despues lo que hace es leerlo como si fuese una cadena...... me estoy liando :/
char promociona a int, ya que después de todo, un char es un entero de 8 bits ;)

Los char se codifican según el código ASCII, haz por ejemplo esto y lo verás.

printf("%c %d", c,c);
Ya lo pille :D, caro si sk lo unico que es un char son muchos 1's y 0's [+risas]
Gracias!
Escrito originalmente por Zeenek
getchar no funciona muy bien en linux (compilador), a mi me ha dado bastantes problemas, sobretodo no pongas su equivalente getche, que esta en la libreria conio.h y no rula en linux.
Para que gecthar funcione bien, ya que a mi no me iba pon lo siguiente:

ch = getchar();
while (getchar() != '\n');


donde ch, es la variable


No se, los getchar() los he usado bastante y son comunes creo yo. Yo no he tenido problemas. Simplemente pillan un char, el ultimo que escribas. Tambien se usan para cosas como estas, que he visto en libros:

ch=0;
while(!ch) {
  hacer_cosas();
  ch=getchar();
}


Saludos
Todavía yo estoy usando el getchar() para una práctica de SSOO, en concreto hacer una shell, y sin ningún problema.

Lo único que pasa es en el debug, que se hace más complicado, ya que las entradas y salidas estándar se hacen a un buffer ;)

gets() no es nada recomendable usarlo, ya que no comprueba el tamaño del buffer, y ahí es donde empiezan los buffer overflow :-)
Escrito originalmente por Churly
gets() no es nada recomendable usarlo, ya que no comprueba el tamaño del buffer, y ahí es donde empiezan los buffer overflow :-)


Efectivamente, si leemos en el man de los gets()
FALLOS
       Puesto que es imposible saber,  sin  conocer  de  antemano  los  datos,
       cuántos  caracteres  va  a  leer gets(), y puesto que gets() continuará
       guardando caracteres una vez alcanzado el final del búfer, su empleo es
       extremadamente peligroso. Muchas veces ha sido utilizado para comprome-
       ter la seguridad de un sistema. En su lugar emplee fgets() siempre  que
       pueda.


fgets es lo mismo, solo que especificas el flujo (stdin para el caso del teclado) y un tamaño maximo de buffer (que tendria que ser sizeof(s) si s es la cadena donde guardamos lo que nos devuelva fgets)

Saludos
PD: Un poco mas y nos montamos un manual de buenas maneras de C XD
PD: Un poco mas y nos montamos un manual de buenas maneras de C


Eso me lo he preguntado antes, que al paso que vamos...
Escrito originalmente por Rurouni
Mucho me temo que esto funcionará bien poco en algunos SO... solo en los Unix y familia.

Pero bueno, también puedes usar TIPEX :D


Sips [oki]

En windows puedes usar

system("cls")



Un saludo [ginyo]
Escrito originalmente por billyberjas

es incorrecto
...
sería
...
Ya que si pones = lo que haces es asignar el valor 'a' a la variable pakito.
...
Saludines [poraki]
Warra! que es pseudocódigo!!!! :P

TPTN :-p
Me he puesto a modificar (esque esto de empezar el isti que malo es xD)lo del scanf() por getchar y no me funciona.... al comparar las cadenas me las da por invalidas [buuuaaaa]. Lo e puesto justo despues de que de todas las opciones asi:
while((opcion=getchar())!='\n');
y esque asi lo unico que me lee es un binario, aunque he probado a ponerlo como int, para ver si lo reconocia pero nada [decaio] .
Subo el programa para ver si es algo que tengo mal por ahi o que......

Saludos y Muchisimas gracias!

Adjuntos

He estado probando y tienes que quitar el while((opcion=getchar())!='\n') y canviarlo por opcion=getchar().
Dentro del switch, en el case'b', antes del scanf("%c",&opcion2) tienes que poner un fflush(stdin), pq sino te dice directamente que la opcion es incorrecta sin introducir nada, y quitar el que hay debajo del scanf, y al final de este case ta falta un break.
Por ultimo, al final del todo, despues de while(opcion!='c'), te falta un return 0.

Un saludo [oki]
Antes del opcion=getchar() que te he dico que pongas, tambien falta un fflush(stdin).

Por cierto, intenta poner el codigo un poco separado del principio, por ejemplo asi:

void e_1()
{
        int ax=0;
   int b=0;
   int c=0;
   int res=0;
   char more='s';
   char operador;

   limpia_pantalla();
}


y el de los switch asi:

switch(opcion)
{
        case 'a':
                    e_1();
                    break;
        case 'b':
                    printf("Opciones:\n");
                    printf("a.Ecuacion completa\n");
                    printf("b.Ecuacion sin termino independiente\n");
                    printf("c.Ecuacion con termino independiente\n");
            printf("\n Opcion: ");
            fflush(stdin);
                    scanf("%c",&opcion2);
                      break;
}


Asi queda mucho mas elegante, y se lee mejor [ginyo]

Por cierto, cuando haces limpia_pantalla(), no hace falta que pongas antes un void limpia_pantalla().
Escrito originalmente por Rurouni
Warra! que es pseudocódigo!!!! :P

TPTN :-p


¿Joer, que narices es TPTN? :-? :-? [comor?]

Yo me sé TQTC (Tranqui que te cagas) Simpons ownz me
Escrito originalmente por [Madox]
Por cierto, intenta poner el codigo un poco separado del principio, por ejemplo asi


Ummmm..... ¿solo muevo lo del principio o todo el codigo?

PD: al final le cambio el nombre al hilo y le llamo "Buenas maneras en C" xD
Escrito originalmente por \-\adEs


Ummmm..... ¿solo muevo lo del principio o todo el codigo?

PD: al final le cambio el nombre al hilo y le llamo "Buenas maneras en C" xD


Todo el codigo, menos las cabeceras de las funciones y los corchetes [oki]
Escrito originalmente por billyberjas


¿Joer, que narices es TPTN? :-? :-? [comor?]

Yo me sé TQTC (Tranqui que te cagas) Simpons ownz me
T P T N (te peten) :D (cariñooousamente claro... [buenazo] )

P.D: El capítulo de la nueva niña pija que llega al colEgio, me lo sé de memoria...

ANTENA 3, COMPRA MÁS CAPÍTULOS!!!!
39 respuestas