Why "result" value is always equal to zero? - c++

I'm going through a MOOC about an introduction to c++, and am stuck in an exercise about functions. The exercise is about a program that changes a number to the way it was read.
For example:
"1" is read like "one one" so the next number should be
"11" which is read like "two ones" the next number is
"21" -> "one two and one one"
"1211" -> "one one and one two and two ones"
"111221" -> "three ones and two twos and one one "
"312211"..... and so on
The user should give the starting number and the number of times we should do this operation, and the program should output the last number. Like in the example the input should be "1 5" and the program should print "312211". In the program they just asked to write three functions to complete the code they gave us.
void ajouter_chiffre_droit(int& nombre, int chiffre);
void dire_chiffre(int& nombre, int repetitions_chiffre, int chiffre);
int lire_et_dire(int nombre);
The part of the program they gave us is this and we should fill the three functions above:
#include <iostream>
using namespace std;
int separer_chiffre_gauche(int& nombre)
{
int dix(1);
int temp(nombre);
while (temp >= 10) {
dix *= 10;
temp /= 10;
}
nombre %= dix;
return temp;
}
/*****************************************************
* Compléter le code à partir d'ici
*****************************************************/
void ajouter_chiffre_droit(int& nombre, int chiffre)
{
}
void dire_chiffre(int& nombre, int repetitions_chiffre, int chiffre)
{
}
int lire_et_dire(int nombre)
{
}
/*******************************************
* Ne rien modifier après cette ligne.
*******************************************/
void repeter_lire_et_dire(int& nombre, int fois)
{
while (fois-- > 0) {
nombre = lire_et_dire(nombre);
}
}
int main()
{
int nombre(1);
int fois(1);
cin >> nombre >> fois;
repeter_lire_et_dire(nombre, fois);
cout << nombre << endl;
return 0;
}
My solution:
void ajouter_chiffre_droit(int& nombre, int chiffre)
{
nombre *= 10 + chiffre;
}
void dire_chiffre(int& nombre, int repetitions_chiffre, int chiffre)
{
ajouter_chiffre_droit(nombre, repetitions_chiffre);
ajouter_chiffre_droit(nombre, chiffre);
}
int lire_et_dire(int nombre)
{
int nombre_temp(nombre), chiffre(0), chiffre_prec(0), rep(1), resultat(0);
chiffre_prec = separer_chiffre_gauche(nombre_temp);
do
{
chiffre = separer_chiffre_gauche(nombre_temp);
if(chiffre == chiffre_prec)
{
++rep;
}
else
{
dire_chiffre(resultat, rep, chiffre_prec);
rep = 1;
chiffre_prec=chiffre;
}
}while(nombre_temp!=0);
return resultat;
}
The function lire_et_dire always returns the value 0 and i don't know why if you could please help me that will be great, thanks!
If you didn't understand the problem from me "probably", please read the official problem text here it's exercise number 1.

Related

How do you compare and sort a specific parameter within a class?

My professor has asked us to make a program that will take a user's input and continue reading until the end of input. Only then, can the program output what the user has typed.
Input should be based on video title, it's url, comments made on the video, length (in minutes), and rating (in *).
For example:
United Break Guitars, https://www.youtube.com/watch?v+5YGc4zOqozo, Great example of one person getting a giant company to listen, 4.5, ***, Space Versus Tabs, https://www.youtube.com/watch?v=SsoOG6ZeyUl, Decide for yourself: spaces or tabs?, 2.83, ****
Up until what is explained, I have completed and tested to see if everything works. My problem is the next part of the project which requires the user to choose between Rating, Length, or title then sort them based on what the user chose.
If I chose Rating, then the input above should be sorted from highest rated video to lowest.
This is what I have so far:
#include <iostream>
#include <stdlib.h>
#include <cstring>
#include <algorithm>
using namespace std;
#include "video.h"
int main()
{
string user, url, comment, title;
int rating;
double length;
int i = 0, last = 0;
Video *videoObj[100];
Video *temp[100];
// specifies how the videos should be sorted
cin >> user;
cin.ignore();
while (getline(cin,title) ) {
getline(cin, url);
getline(cin, comment);
cin >> length;
cin >> rating;
cin.ignore();
videoObj[i] = new Video(title, url, comment, length, rating);
i++;
last++;
}
temp[i] = new Video(title, url, comment, length, rating);
if(user=="rating"){
for(int i = 0; i < last - 1; i++){
for(int j = i+1; j< last; j++){
if(videoObj[i] -> Rating(videoObj[j])) {
temp[i] = videoObj[i];
videoObj[i]= Rating(videoObj[j]);
Rating(videoObj[j]) = temp[i];
}
}
}
}
for(int i= 0; i < last; i++)
{
videoObj[i]->print();
}
//delete[] videoObj;
return 0;
}
video.cpp file:
#include <iostream>
#include <algorithm>
using namespace std;
#include "video.h"
Video::Video(string video_title, string video_link, string video_comment, double video_length, int video_number)
: title(video_title), link(video_link), comment(video_comment), length(video_length), rating(video_number)
{
}
bool Video::Rating(Video *videoObj) {
if(rating > videoObj-> rating )
{
return true;
}
else
{
return false;
}
}
void Video::print(){
string star;
switch(rating){
case 1:
star = "*";
break;
case 2:
star = "**";
break;
case 3:
star = "***";
break;
case 4:
star = "****";
break;
case 5:
star = "*****";
break;
}
cout << title << ", " << link << ", " << comment << ", " << length << ", " << star << endl;
}
void Video::temp(){
title, link, comment, length, rating;
}
video.h file:
#ifndef VIDEO_H
#define VIDEO_H
using namespace std;
class Video {
public:
Video(string video_title, string video_link, string video_comment, double video_length, int video_number);
void print();
bool Rating(Video *videoObj);
void temp();
private:
string title;
string link;
string comment;
double length;
int rating;
};
#endif
I honestly have no idea how to implement the bubble sort correctly. I have looked up multiple different videos on youtube and posts on stackoverflow, but I can't seem to figure out how to sort a specific parameter within my class.
My professor gave us these instructions for sorting within our class:
When sorting the videos you need to be able to determine how two video objects should be
ordered. The easiest way to do this is to write member functions to handle the comparisons in
class Video. For example, this method could be used when sorting the videos by length:
// return true if the current video is longer than the given video (other) ,
// otherwise return false
bool Video :: longer(Video *other) {
return (mlength > other -> mlength ;
}
I'm not even sure if I did that part correctly in my video.cpp file. Any ideas on how I can get the sorting method to work properly?
Please be gentle, I'm very new to programming. I realize my bubble sort is wrong as well, I just don't know where to start fixing it...
I'd normally use std::sort with a comparison operator for each field you want to be able to compare. You can implement those either as named classes:
struct by_title {
bool operator()(Video const &a, Video const &b) {
return a.title < b.title;
}
};
struct by_rating {
bool operator()(Video const &a, Video const &b) {
return a.rating < b.rating;
}
};
// ...
std::sort(videos.begin(), videos.end(), by_rating);
std::sort(videos.begin(), videos.end(), by_title);
...or you can use a lambda expression to define a comparison:
// sort by rating
std::sort(videos.begin(), videos.end(), [](auto &a, auto &b) { return a.rating < b.rating; });
// sort by title
std::sort(videos.begin(), videos.end(), [](auto &a, auto &b) { return a.title < b.title; });

Segmentation fault (core dumped) C++ Object Oriented Programming

I'm a student of system engineering, 2nd semester of the ULA (Universidad de los Andes)
So, I'm programming a c++ mini project for university. The project consists of making a draft of a software oriented to buying and selling crypto currencies, however, since yesterday I've been getting a problem with it (a segmentation fault core dumped specifically)... So, as this page had been helpful with my previous programs and this time I didn't find something that could have helped me, I decided to register and ask in case someone is willing to help me.
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class usuario {
private :
string username[10], password[10];
int aux;
public :
usuario();
void setUnamep(string, string, int);
string getUnamep();
void setPass(string);
string getPass();
int DataAcc(string, string);
~usuario();
};
class moneda {
protected :
float cantidad;
public :
moneda(float);
void setCant(float);
void getCant();
~moneda();
};
class bitcoin : public moneda {
private :
float btc[20];
public :
bitcoin (float);
void setBuy(float, float[]);
void getBuy();
void mostrarc(float);
~bitcoin();
};
usuario::usuario () {
}
void usuario::setUnamep(string username_, string password_, int aux_) {
string PreUser[20], aux_2;
aux = aux_;
for (int i= 1; i <= aux; i++) {
username[i] = username_[i];
password[i] = password_[i];
cout<<"\nEnter an username: ";
cin>>username[i];
cout<<"Enter a password: ";
cin>>password[i];
username[0] = "."; //pass 1 leer
for (int v = 0 ; v < i; v++) {
if (username[v] == username[i]) {
cout<<"\nUsername already in use. Choose another"<<endl;
username[i] = "null";
password[i] = "null";
i--;
v = 20000;
}
}
}
}
int usuario::DataAcc(string InUs, string InPass) {
bool ing = false, ret = false;
int u = 0;
do {
if (InUs==username[u] and InPass==password[u]) {
ing = true;
u = 10;
ret = true;
}
else //////
u++;
}
while (ing == false and u<5);
if (u == 5)
cout<<"\nIncorrect user or password. Try again."<<endl;
if (ing == true) {
cout<<"\nAccount data..."<<endl;
}
return ret;
}
usuario::~usuario() {
}
moneda::moneda(float cantidad_) {
cantidad = cantidad_;
}
moneda::~moneda() {
}
bitcoin::bitcoin(float cantidad_) : moneda(cantidad_) {
}
void bitcoin::setBuy(float cantidad_, float btc_[]) {
int aux;
for (int i = 0; i < 20 ; i++) {
btc[i] = btc_[i];
}
cout<<"How many BTC do you wish to buy?: ";
cin>>cantidad;
btc[aux] = btc[aux] + cantidad;
}
bitcoin::~bitcoin() {
}
int main() {
int opc = 0, aux1;
string InUs, InPass;
int aux2 = 0;
bitcoin b1(0);
cout<<"Welcome to BitZuela 2018, down there you have several options for you to choice which one do you want to run. ";
cout<<"\n\n1. Sign Up."<<endl;
cout<<"2. Log in."<<endl;
cout<<"3. Finish program."<<endl;
usuario u1;
while (opc >=0 and opc <=2) {
cout<<"\nPress the button of the option you want to run: ";
cin>>opc;
if (opc==1) {
cout<<"\nHow many accounts do you want to register?: ";
cin>>aux1;
u1.setUnamep("null", "null", aux1);
}
if (opc==2) {
cout<<"\nUsername: ";
cin>>InUs;
cout<<"Password: ";
cin>>InPass;
aux2 = u1.DataAcc(InUs, InPass);
if (aux2 == 1) {
b1.setBuy(0,0); //The problem is when this object is created
}
}
if (opc == 3)
cout<<"\nProgram finished."<<endl;
}
return 0;
}
That's it, I would be very grateful if someone can help me solving this problem. Also, if you have a suggestion about another thing, It'll be a pleasure to read it!
There seems to be some trouble with this method
void bitcoin::setBuy(float cantidad_, float btc_[]) {
int aux;
for (int i = 0; i < 20 ; i++) {
btc[i] = btc_[i];
}
cout<<"How many BTC do you wish to buy?: ";
cin>>cantidad;
btc[aux] = btc[aux] + cantidad;
}
The 'aux' variable is used before it is set resulting in undefined behavior.
Also the call is passing a 0 instead of a float[]. The compiler interprets the 0 as a nullptr, resulting a crash in ::setBuy
if (aux2 == 1) {
b1.setBuy(0,0);
Probably some other issues but fixing these will be a step in the right direction
Your core dumped is in the setBuy function. You ask for an array of float, but when you call it in your code, you pass a "0", but you should pass an array of 20 elements.
The aux variable is set inside the function, but I think you should pass it from the signature of the function.
Also, the cantidad variable that you are using inside that function is not the one in the signature (you should remove it from the signature, or add an _ to cantidad).
I also looked into your setUnamep function, you should use an std::map for your username and password management (You can search for an already existing keys in log(n)).

Roman numbers to decimal numbers, getting garbage value

I have to create a program for converting Roman numerals to decimal numbers for which I'm getting garbage value as an output.
The fact is I have double checked my logic and it seems to be correct.
How can I correct it?
Here's my code:
#include<iostream>
#include<cstring>
using namespace std;
class RomanType
{
char str[10];
int d;
public:
void accept()
{
cout<<"Enter Roman No. in capitals:"<<endl;
cin>>str;
convert(str);
}
void convert(char str1[10])
{
int j=0;
for(j=0;j<strlen(str1);j++)
{
if( str1[j]=='I')
{
if(str1[j+1]=='V' || str1[j+1]=='X')
{
d=d-1;
cout<<j<<endl;
}
else
{
d=d+1;
cout<<d<<endl;
}
}
if ( str1[j]=='V')
d=d+5;
if(str1[j]=='X')
{
if(str1[j+1]=='L' || str1[j+1]=='C')
d=d-10;
else
d=d+10;
}
if(str1[j]=='L')
d=d+50;
if( str1[j]=='C')
{
if(str1[j+1]=='D' || str1[j+1]=='M')
d=d-100;
else
d=d+100;
}
if(str1[j]=='D')
d=d+500;
if(str1[j]=='M')
d=d+1000;
}
}
void display()
{
cout<<"It's decimal equivalent is="<<d<<endl;
}
};
main()
{
RomanType obj;
obj.accept();
obj.display();
}
Few points:
Don't directly jump to parsing high value romans. Start with I, V, and X only (i.e. target 1 to 10 first, then 11 to 20, then 21 to 39, 40 to 99, 100 to 499 etc.)
Don't assume that if I is given, it is given before or after V or X. It may be given for itself (eg. II - you else part assumes something).
Assign value of d with zero
Do step debugging, watch value of d and other variables. If debugger isn't good or available, do output the values on each step/iteration.
[Add] You need not to pass str to function convert, since they belong to same class, and convert can/would read the same content.
You didn't initialize d to 0
in convert put d=0 at the start
You didn't initialize d to 0. Please add this at the top of your convert function:
void convert(char str1[10])
{
int j=0;
d = 0;
. . .
OK guys thanks for the help. It's solved now. I had done a blunder and that was initialised d again in convert(), so that had made it as a local variable. See the comments:
#include<iostream>
#include<cstring>
using namespace std;
class RomanType
{
char str[10];
int d;
public:
void accept() // UNNECESSARILY NOT PASSING ANY STRING
{
cout<<"Enter Roman No. in capitals:"<<endl;
cin>>str;
convert();
}
void convert()
{
d=0;// PREVIOUSLY WRIITEN int d=0; so that was the mistake. Yay! it's solved :D
for(int j=0;j<10;j++)
{
if( str[j]=='I')
{
if(str[j+1]=='V' || str[j+1]=='X')
{
d=d-1;
// cout<<d<<endl;
}
else
{
d=d+1;
//cout<<d<<endl;
}
}
else if ( str[j]=='V')
d=d+5;
else if(str[j]=='X')
{
if(str[j+1]=='L' || str[j+1]=='C')
d=d-10;
else
d=d+10;
}
else if(str[j]=='L')
d=d+50;
else if( str[j]=='C')
{
if(str[j+1]=='D' || str[j+1]=='M')
d=d-100;
else
d=d+100;
}
else if(str[j]=='D')
d=d+500;
else if(str[j]=='M')
d=d+1000;
}
}
void display()
{
cout<<"It's decimal equivalent is="<<d<<endl;
}
};
main()
{
RomanType obj;
obj.accept();
obj.display();
}

Peculiar behavior while recursively calling function in C++ and getting two different outputs for the same code with only an extra line with "cout"

#include <iostream>
#include <vector>
#define MAXX 1000
using namespace std;
int number[MAXX], digits=0;
int adjust(int i)
{
if(number[i]<9)
{
cout<<"i = "<<i<<" "; //PROBLEM
(number[i])++;
return i;
}
number[i]=0;
adjust(i-1);
}
void makePalindrome(int head,int tail)
{
int revert;
if(head>tail)
return;
if(number[head]==number[tail])
{
makePalindrome(head+1,tail-1);
}
if(number[tail]<number[head])
{
number[tail]=number[head];
makePalindrome(head+1,tail-1);
}
if (number[tail]>number[head])
{
number[tail]=number[head];
revert=adjust(tail-1);
if(revert<=head)
{
makePalindrome(revert,digits-revert-1);
}
else
{
makePalindrome(head+1,tail-1);
}
}
}
int main(int argc, char const *argv[])
{
long long int num,num_copy;
int head,tail;
int number_reverse[MAXX];
cout<<"Enter the number whose next greater palindrome you want to find" <<endl;
cin>>num;
num_copy=num;
while(num_copy>0)
{
number_reverse[digits]=num_copy%10;
digits++;
num_copy=num_copy/10;
}
//cout<<"Digits = "<<digits<<"\n";
for (int i = digits-1; i >=0; --i)
{
number[digits-i-1]=number_reverse[i];
//cout<<number[digits-i-1]<<" ";
}
head=0; tail=digits-1;
makePalindrome(head,tail);
cout<<"Answer : ";
for (int i = 0; i < digits; ++i)
{
cout<<number[i];
}
cout<<"\n";
return 0;
}
When I am running with an input : 94187978322, it is giving two different answers with and without a "cout" line (line with comment "PROBLEM").
Here's the output:
ishivendra:code shivendraagrawal$ g++ next_palindrome.cpp
ishivendra:code shivendraagrawal$ ./a.out
Enter the number whose next greater palindrome you want to find
94187978322
Answer : 94188078149
ishivendra:code shivendraagrawal$ g++ next_palindrome.cpp
ishivendra:code shivendraagrawal$ ./a.out
Enter the number whose next greater palindrome you want to find
94187978322
i = 7 i = 6 i = 4 Answer : 94188088149
The second output is the desired output. Can you point out the cause of this difference and incorrectness for the first one ?
I figured half of it out, it was a logical error.
I should have written return adjust(i-1).
I still don't know the cause for the peculiarity (There was no compilation or runtime error) but at least my code is running as desired now.

Why do i get wrong values when i multiply a int by a double?

Well, i am trying to do some basic operations in my program, such as subtraction and multiplication ...
i defined "get" and set methods for my classes .... but when i applied the multuplication operation to a double and an int, i get values like: 1.7e-3.17 ....
here is my code:
is in spanish but ... i am sure you will understand
MAIN:
#include <cstdlib>
#include <iostream>
#include "Tienda.h"
#define numeroClientes 2
using namespace std;
int main(int argc, char *argv[])
{
Cliente arregloClientes[numeroClientes];
string name;
int day, amount,i;
Tienda tienda = Tienda();
for(i=0; i<numeroClientes; i++){
system("cls");
cout<<"Ingrese el nombre del cliente: ";
cin>>name;
arregloClientes[i].setNombre(name);
cout<<"Ingerese numero de garrafones: ";
cin>>amount;
arregloClientes[i].setNumeroGarrafones(amount);
cout<<"Ingrese el dia de la compra"<<endl;
cout<<"0; Lunes 1; Martes 2; Miercoles 3; Jueves 4; Viernes: ";
cin>>day;
arregloClientes[i].setDia(day);
}
//Calculo del monto a pagar
for(i=0; i<numeroClientes; i++){
tienda.calcular(arregloClientes[i]);
}
system("cls");
//Impresion de los datos
for(i=0; i<numeroClientes; i++){
cout<<"------------------------"<<endl;
arregloClientes[i].imprimir();
}
cout<<"------------------------"<<endl;
tienda.imprimir();
cout<<"\n\n";
system("PAUSE");
return EXIT_SUCCESS;
}
class Cliente {
/* Atributos privados */
private:
string nombre;
int numeroGarrafones;
int dia; // 1 - 5
double totalCancelar;
/* Metodos publicos */
public:
string getNombre();
int getNumeroGarrafones();
int getDia();
double getTotalCancelar();
void setNombre(string nomb);
void setNumeroGarrafones(int nG);
void setDia(int d);
void setTotalCancelar(double tC);
void imprimir();
string imprimirDia();
}; // fin de clase Cliente
The problem is here:
void Tienda::calcular(Cliente persona){
double aux,total;
int garrafones= persona.getNumeroGarrafones();;
arregloDias[persona.getDia()]= arregloDias[persona.getDia()] + persona.getNumeroGarrafones();
aux = garrafones * precioVenta - garrafones * precioCosto;
ganancia = ganancia + aux;
total = garrafones * precioVenta;
persona.setTotalCancelar(total);
} // fin de calcular
This one:
aux = garrafones * precioVenta - garrafones * precioCosto;
The operation multiply ... generated numbers as i said before
anyone knows what happen ?
I do not believe it is an int * double problem, but an unitialised member problem.
Go to the line of interest:
aux = garrafones * precioVenta - garrafones * precioCosto;
Before that line, add the code: (or use your trusted debugger if you know how to set breakpoints and check expressionvalues)
printf("--> %d %.6g %.6g\n", garrafones, precioVenta, precioCosto);
I believe that you will probably find that member instances of your Tienda object are unitialised and contain "random" values.
The only moment you're using "tienda" before calculating is when you call the constructor. You should check if you're initializing precioVenta and precioCosto in that constructor, i guess those are fixed values and belong to the "Tienda" class in case those are not global variables (and in that case you should initialize it anyway).