dudas de novata en c++

L

Buenas chicos estoy haciendo un curso de c++ para finanzas y estoy algo perdida. Tengo que hacer un ejercicio pero no se muy bien cómo.

Quiero que el sistema le pida al usuario un valor y si no es correcto que se lo vuelva a pedir, cuando sea correcto lo usare en una formula.

int main()
{
 
std::cout << "Please enter a valid and correct Strike Price: ";
int S;
 std::cin >> S;
 while(S < 0){
  std::cout << "Please enter a valid and correct Strike Price: ";
    int S;
 std::cin >> S;}

Como es el valor de algo positivo habia pensado en usar ese código, que S sea mayor que 0. El problema es que dejo la variable S como estatica (supestamente no hay problema porque la puedes machacar y volver a escribir) y me gustaría cambiarla con la misma pregunta hasta que sea mayoar que 0.

A ver si alguien me puede orientar un poco porque ando perdida y ya he mirado por todos lados y las soluciones que dan son muy complicadas y estoy segura que siendo un curso de principiantes tiene que haber una manera más fácil.

Josepanaero

Un par de cosas:

  • No hace falta que declares S de nuevo dentro del bucle while (elimina el "int S;" dentro del bucle while).
  • Puedes usar un do-while en lugar de un while para evitar repetir el mismo código dos veces.

Un saludo.

1 respuesta
B

#1 - Puede ser un valor decimal? De ser asi asegurate de usar double, porque sino solo vas a coger la parte entera del numero que te entren.

 - intenta declarar variables en minuscula.
 - Cuando declaras una variable estas reservando espacio en memoria para ese valor. No hace falta que vuelvas a declarar esa misma variable otra vez dentro del bucle, simplemente haz el cin >>s
1 respuesta
FrioneL

Primero tienes que saber cual es el dominio de esa variable, que tipos de valores son validos o no. Si con saber que es positivo ya te sirve, entonces esta bien comprobarlo de esa manera.

bool isCorrectInput(int value)
{
    // Todas las comprobaciones que tengas que hacer:
    bool correct = value > 0;

if(!correct)
{
    std::cout << "The introduced value is incorrect. Please, introduce a positive number: ";
}

return correct;
}

int main()
{
    std::cout << "Please enter a valid and correct Strike Price: ";
    int value;

do
{
    std::cin >> value;
}
while(!isCorrectInput(value));

// hacer algo con el value 
}
1 respuesta
L

#2 #3 #4 Gracias por las respuestas y aporte. He probado lo que ha comentado frionel y se acerca a lo que estoy buscando pero cuando lo compilo ( creo que se dice asi) solo lo repite una vez cuando es negativo y pasa directamente a la siguiente linea. Os pego el código que llevo y no asigna valor a la variable K ( la deja en blanco) y pasa a la siguiente linea.

#include <iostream>

bool iscorrectinput(double k)
{ bool correct = k > 0;
 if(!correct)
  std::cout << "Please enter a valid and correct Strike Price: "<< std::endl;
 else
   return K;
}

int main()
{
     std::cout << "Please enter a valid and correct Strike Price: ";
    double k;
 
 do{
  std::cin >> k;    
} while(!iscorrectinput(kiss));
std::cout << "Please enter an risk-free rate: "; double r; std::cin >> r;
BLZKZ

has puesto incorrectinput(kiss), cuando no has declarado "kiss" (o eso o es tarde y estoy ciego xD)

1 respuesta
FrioneL

Eso y sobra el 'else' de la funcion booleana. Siempre quieres retornar el resultado de la comprobacion, tanto si es correcta como no, ya que es ese valor el que cortara el bucle en el que estas recogiendo el input.

Me he dado cuenta de que el texto que aparece cuando introduces un valor incorrecto es el mismo que el inicial xd. Deberia ser un mensaje que aclarase que el valor introducido es incorrecto:

std::cout << "The introduced value is incorrect. Please, introduce a positive number: ";

O si te da igual, puedes simplificarlo y hacerlo incluso mas simple:

int main()
{
    double value;

do
{
    std::cout << "Please enter a valid and correct Strike Price: ";
    std::cin >> value;
}
while(value <= 0);

// hacer algo con el value 
}

A las 2 y escribiendo c++, me voy a dormir xd.

1 respuesta
L

#7 #6 Vale muchisimas gracias a todos, ya lo solucioné. Faltaba un std::cin >> k; en el bucle para reiniciarlo. Lo dejo aqui arreglado para si alguien lo necesita en un futuro. Gracias de verdad.

#include <iostream>

bool iscorrectinput(double k)
{ bool correct = k > 0;
 if(!correct){
  std::cout << "Please enter a valid and correct Strike Price: "<< std::endl;
std::cin >> k;
 }
   return K;
}

int main()
{
     std::cout << "Please enter a valid and correct Strike Price: ";
    double k;
 
 do{
  std::cin >> k;    
} while(!iscorrectinput(kiss));
std::cout << "Please enter an risk-free rate: "; double r; std::cin >> r;
1 respuesta
m4andg4

lol lo de las tabulaciones hay que mejorarlo laurota, a la gente que lee el código le gusta el orden y mucho.

B

almenos tiene las variables en ingles, asi que ya programa mejor que el 90% de usuarios del foro xD

2 1 respuesta
B

#10 Menuda gilipollez. Nunca he entendido la gente que, teniendo como lengua materna el español o cualquier otro idioma, no pone nombres ni comenta en su idioma, si no en inglés. Obviamente, me refiero a códigos para uno mismo que se pican por aprender, como es este caso. Me parece overcomplicarse la vida y ponerse trabas.

Y tampoco entiendo la gente que calificáis la calidad de los programadores por chorradas como la nomenclatura, indentación y otras cosas que se pueden arreglar con refactors. Eh, que a lo mejor luego es un inútil integral que mete 30 bugs por línea, pero pone las variables en inglés.

1 1 respuesta
Josepanaero

#11

  • Escribir el código en inglés puede ser útil por si en el futuro necesitas compartir tu código en sitios como github, o parte de tu código en stackoverflow, por si necesitas trabajar en un equipo en el extranjero, etc. Nunca sabes lo que puede pasar en un futuro. Un amigo creó un proyecto en la facultad, todo en español, y ahora lo ha subido a github, y ese código no va a poder "llegar" a millones de personas, por el simple hecho de no estar en inglés. Nos guste o no, el inglés es necesario en nuestra profesión.

  • Escribir código claro y limpio denota que eres un programador que se preocupa por su código, que es ordenado y, sobre todo y más importante, que se preocupa por sus compañeros, que son los que van a tener que leer el código más tarde. A escribir un código limpio no se llega mediante refactors.

Un saludo.

5 2 respuestas
FrioneL

#8 Ese codigo esta mal por varios motivos. Si te esta funcionando sera de pura suerte.

Utiliza el ultimo que te he puesto y olvida lo de la funcion porque quizas te introduci un concepto que aun no has aprendido.

De todas formas, te digo lo que hay mal en tu codigo:

  • Estas poniendo en el return de la funcion booleana un double. Que pasa? Que el compilador cuando ve que tiene que devolver una booleana pero en realidad le has especificado un double, hace una conversion para adaptarlo.

Que pasa con una conversion de double a booleana? Pues si no me equivoco, siempre vas a devolver que el valor introducido es correcto a no ser que pongas un 0. Prueba a poner un valor negativo y veras que tambien te dice que es correcto.

2 respuestas
B

#12 Sobre tu primer punto: citándome a mi mismo Obviamente, me refiero a códigos para uno mismo que se pican por aprender, como es este caso.

Sobre tu segundo punto: Estoy de acuerdo en lo que has dicho. Te hace un programador más ordenado, y denota preocupación por los compañeros. En serio, ninguna queja. A lo que me refería era a gente que identifica la calidad/nivel de un programador sólo por cosas de este estilo, que poca no es. Ya que mencionas stackoverflow, más de una vez me ha pasado que he mirado posts dónde alguien se queja de que cierto fragmento de código no funciona, y más de uno comenta "you suck at naming variables".
Sobre los refactors: Era una exageración y una asunción implícita de que hablo de gente que no escribe código con el culo.

1 respuesta
BLZKZ

#14 si aprendes mal lo harás mal, lo mejor es intentar hacerlo siempre bien.

Si queréis discutir abrid un hilo, este no es el lugar.

L

#13 Llevabas razón totalmente, lo mire ayer y al final es como tu decias.

Las variables estan en ingles porque el manual que estamos siguiendo esta en ingles pero me parece correcto lo que han comentado sobre que es mejor hacerlo en ingles para poder difundirlo mejor y trabajar con gente de fuera. ( Aunque definitivamente de momento no es mi caso) xD

Siguiendo con el ejercicio me esta saltando un error que no entiendo. He creado un header para hacer la función normal que necesito en la formula y he incluido la formula en el cpp para usarla en el int main() pero no sé por qué me salta un error diciendo que no se han incluido los datos necesarios en la función. Os dejo el código a ver si alguien ve el error

Primero el del header:

#include <cmath> 

double normcdf(double x, double mu = 0.0, double sigma = 1.0) {
double b1 =  0.319381530, b2 = -0.356563782,
     b3 =  1.781477937, b4 = -1.821255978,
     b5 =  1.330274429, p  = 0.2316419   ,
     c  =  0.3989422804; //c = 1/sqrt(2*pi) con pi = 3.14159...

x = (x-mu)/sigma;
if(x >= 0.0) {
  double t = 1.0 / ( 1.0 + p * x );
  return (1.0 - c * exp( -x * x / 2.0 ) * t *
  ( t *( t * ( t * ( t * b5 + b4 ) + b3 ) + b2 ) + b1 ));
}
else {
  double t = 1.0 / ( 1.0 - p * x );
  return ( c * exp( -x * x / 2.0 ) * t *
  ( t *( t * ( t * ( t * b5 + b4 ) + b3 ) + b2 ) + b1 ));
}
}

Segundo el del CPP:

#include <iostream>
#include <cmath>
#include "normal.h"

bool iscorrectinput(double k)
{
bool correct = k > 0;
 if(!correct){
  std::cout << "The introduced value is incorrect. Please, introduce a positive Strike Price:";
  
} return correct; } double eblsprice(char type, double sprice, double k, double T, double r, double v){ double d1, d2; d1 = (log(sprice/k)+(r+v*v/2)*T)/(v*sqrt(T)); d2 = d1-v*sqrt(T); if(type == 'c') // Option CALL return sprice * normcdf(d1) - k * exp(-r*T) * normcdf(d2); else if(type == 'p') // Option PUT return k * exp(-r * T) * normcdf(-d2) - sprice * normcdf(-d1); else return 0; } int main() { std::cout << "Please enter a Strike Price: "; double k; do{ std::cin >> k;
} while(!iscorrectinput(k));
std::cout << "Please enter a risk-free rate: "; double r; std::cin >> r;
std::cout << "Please enter a volatily: "; double v; std::cin >> v;
std::cout << "Please enter time to maturity: "; double T; std::cin >> T;
std::cout << "Please enter a type: "; char type; std::cin >> type; std::cout << "Please enter underlyig price: "; double sprice; std::cin >> sprice; std::cout << "The price for the option is equal to "<< eblsprice(); system("pause"); return 0; }

Si los variables las voy rellenando según saltan los cout y cin no entiendo porque me salta el error de que la funcioón no acepta 0 argumentos.

Muchas gracias por las respuestas.

1 respuesta
BLZKZ

declaras la función así --> double eblsprice(char type, double sprice, double k, double T, double r, double v)

y luego intentas llamarla así qual to "<< eblsprice();

Obviamente no le estás pasando ningún argumento cuando necesita 6

1 respuesta
L

#17 Los argumentos son los de arriba,no? osea yo voy pidiendo variables a través de los cout y cin, y cuando hago la función se rellenan las variables que he pedido en la función de más arriba.

Si no es así creo que no lo estoy entendiendo.

1 respuesta
BLZKZ

#18 la función de arriba es una definición, no se le pasan automáticamente los argumentos. Tu defines el nombre de la funcion, sus 6 argumentos y su comportamiento, entonces luego la intentas llamar así eblsprice(), ahí tienes que indicarle las 6 variables, y no lo estás haciendo.

Viendo que te fallan las bases, por qué en lugar de escribir código no lees tus apuntes de nuevo las veces que haga falta, hasta que entiendas lo que estás haciendo?

De hecho yo empezaría por la página 1 de nuevo, y haz los ejercicios con los apuntes/temario/lo que sea en la mano, porque te estamos haciendo los deberes y deberías aprender tú a hacerlos.

1 1 respuesta
Joey

Pregunta noob, ¿por qué no se añade al código la siguiente línea?

using namespace std;

De esta manera se evita poner std:: delante de los operadores cin, cout y alguno más que otro.

2 respuestas
Xustis

#16 Una cosa, creo que es mas fácil usar el "using namespace std;" que andar poniendo std todo el rato...

Xustis

#20 en serio...jajajaja

L

#19 gracias, conoces alguna página que te explique las cosas claras es que los manuales que estoy usando dan cosas por asumidas y me parece dificil seguirlos. Gracias de nuevo

#20 Yo he leido que se puede hacer pero no es correcto pero soy una noob y no te fies xD

2 respuestas
Xustis

#23 Pues es lo que enseñan en la universidad, nada mas empezar te dicen que uses eso, asi que digo yo que será correcto no se xD

Lo acabo de buscar y dicen que es una mala práctica porque asi incluyes el contenido de namespace en el código, supongo que será como una librería o algo así no se, igualmente me parece un auténtico coñazo andar escribiendolo siempre y si lo que estás haciendo es aprendiendo a programar...

1 respuesta
rafag

#23 Yo te recomiendo los vídeos de Jesús Conde, tiene muchos en Youtube sobre distintos lenguajes y herramientas, entre ellos C++.

#24 Desde mi punto de vista, usar using namespace ---; puede causar conflictos entre funciones, variables o clases que tengan el mismo nombre. Al fin y al cabo, los espacios de nombres están para que puedan convivir cosas con el mismo nombre sin que interfieran. Aunque no creo que haya nada malo en usarlos en proyectos pequeños.

Un saludo.

L

#12 #13 Sigo con mi periplo hasta aprender c++. Ahora mismo estoy con los input/output files y tengo una duda:

Soy capaz de exportar los datos a ese archivo de texto pero se me corta los resultados en el archivo de texto. Cuando hago la función fs solo imprime la primera linea y una variable y lo que me gustaría sacar es algo así:

strike price: variable k.
tipo de interes: varaible r.

Si pongo dos funciones fs seguidas solo me imprime la primera en el archivo de texto si lo hago a través del /n me pasa lo mismo solo me muestra la primera linea. He probado varias cosas y no sé porque solo me imprime la primera en el txt.

¿Alguien tiene alguna idea?

char cadena[128];
  
ofstream fs("Optionresult.txt");
fs << "strike price:\t \t \t "<< k <<endl; fs.close(); ifstream fe("Optionresult.txt"); fe.getline(cadena, 128); cout << cadena << endl;
1 respuesta
rafag

#26 Mira si esto te ayuda:

void guardar()
{
	int k = 25;
	int r = 20;
/*Más datos ...*/

ofstream os("salida.txt");

os << "strike price: \t \t \t " << k << endl;
os << "tipo de interes: \t \t \t " << r << endl;

os.close();

}

void cargar()
{
	ifstream is("salida.txt");

while (!is.eof()) //Mientras no se haya leído todo.
{
	string linea;
	getline(is,linea); //Se lee una línea.
	cout << linea << endl; //Y se imprime.

}

is.close();
}

He usado la función getline para poder trabajar con strings en vez de arrays de caracteres, así te puedes desentender de su tamaño.

Un saludo.

Usuarios habituales