Struct doesn't print with cout - c++

I'm trying to print the structure in an array whose int prejetih member is highest.
#include <iostream>
using namespace std;
struct Tekma {
int prejetih;
};
Tekma najvec_kosev(Tekma tekme[]) {
int maksi = 0, index = 0;
for (int i = 0;i < 2;i++) {
if (maksi < tekme[i].prejetih) {
index = i;
maksi = tekme[i].prejetih;
}
}
return tekme[index];
}
void vpis(Tekma tekme[]) {
for (int i = 0;i < 2;i++)
cin >> tekme[i].prejetih;
}
int main() {
Tekma tekme[2];
vpis(tekme);
cout << najvec_kosev(tekme);
}
The compiler reports
C++ no operator matches these operands
operand types are: std::ostream << Tekma
over cout << najvec_kosev(tekme);

Here using a solution with std::vector and fixing your cout problem:
#include <iostream>
#include <vector>
using namespace std;
struct Tekma {
int prejetih;
};
Tekma najvec_kosev(vector<Tekma>& tekme) {
Tekma lowest = tekme[0]
for(auto& t : tekme) {
if(lowest.prejetih < t.prejetih) {
lowest = t;
}
}
return lowest ;
}
void vpis(vector<Tekma>& tekme) {
int input;
while(true) {
cin >> input;
// Check if the input is valid else quit the loop.
if(input == valid) {
Tekma newStruct = {input};
tekme.push(newStruct);
}
else {
// Stop the loop
break;
}
}
}
int main() {
vector<Tekma> tekme;
vpis(tekme);
cout << najvec_kosev(tekme).prejetih; // This fixes your error.
}

Related

Unknown Type Name when using threads

I am trying to find the minimum vertex cover by giving the vertex and edge input in specific format from the user using threads. Here is my code:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <cctype>
#include <list>
#include <set>
#include <vector>
#include <climits>
#include <memory>
#include <algorithm>
#include <pthread.h>
#include <unistd.h>
#include "minisat/core/Solver.h"
using namespace std;
static void *AVC2_Vertex_Cover(void *);
void min_vertex_cover_algorithm(Graph &graph_builder){
int ret;
pthread_t AVC2_thread;
ret = pthread_create(&AVC2_thread, NULL, AVC2_Vertex_Cover, &graph_builder);
if(ret)
exit(1);
pthread_join(AVC2_thread, NULL);
pthread_exit(NULL);
}
struct Edge{
unsigned v1,v2;
};
typedef std::vector<unsigned> Vertex_vector;
typedef std::list<unsigned > Vertex_Adjacency_list;
typedef std::vector<Vertex_Adjacency_list> Adjacency_Traversal_list;
struct Graph{
std::size_t no_of_edges;
Adjacency_Traversal_list adjacency_list;
void initialize_graph(unsigned vertices_number);
void construct_edge(Edge edge);
void clear(unsigned vertex);
};
void Graph::initialize_graph(unsigned num){
adjacency_list.clear();
no_of_edges = 0;
adjacency_list.resize(num,{});
}
void Graph::construct_edge(Edge edge) {
auto &literal_1 = adjacency_list[edge.v1];
auto &literal_2 = adjacency_list[edge.v2];
literal_1.push_back(edge.v2);
literal_2.push_back(edge.v1);
no_of_edges ++;
}
void *AVC2_Vertex_Cover(void *input)
{
Graph g = *(const Graph *)input;
unsigned int V = g.adjacency_list.size();
bool visited[V];
for (int i=0; i<V; i++)
visited[i] = false;
for (int u=0; u<V; u++)
{
if (visited[u] == false)
{
for(int x : g.adjacency_list[u])
{
int v = x;
if (visited[v] == false)
{
visited[v] = true;
visited[u] = true;
break;
}
}
}
}
// Print the vertex cover
std::cout << "APPROX-VC-2: ";
for (int i=0; i<V; i++){
if (visited[i])
if(i == V-1)
cout << i << std::endl;
else
cout << i << ",";
}
}
void *IO_thread(void *)
{
Graph &graph_builder = *new Graph();
char character_input;
string my_input;
unsigned int no_of_vertices = 0;
string edge_stream;
char prev_choice = ' ';
while (getline(cin, my_input))
{
istringstream stream_string(my_input);
while (stream_string >> character_input)
{
character_input=(toupper(character_input));
try
{
switch (character_input)
{
case 'V' :
if (prev_choice == 'V')
{
cerr << "Error: V must be followed by E only.\n";
break;
}
else
{
stream_string >> no_of_vertices;
if(no_of_vertices <= 0)
{
throw "Invalid number of vertices";
}
graph_builder.initialize_graph(no_of_vertices);
prev_choice = 'V';
break;
}
case 'E' :
{
unsigned int flag_Entry = 0;
if ( prev_choice == 'E')
{
cerr << "Error: V and E always occur together.\n ";
break;
}
else
{
stream_string >> edge_stream;
istringstream edge_stream_character(edge_stream);
char edg_char;
unsigned int temp = 0;
unsigned int v1;
unsigned int v2;
edge_stream_character >> edg_char;
while (edg_char != '}')
{
edge_stream_character >> edg_char;
if (edg_char == '}')
{
flag_Entry = 1;
break;
}
else
{
edge_stream_character >> temp;
v1 = temp;
edge_stream_character >> edg_char;
edge_stream_character >> temp;
v2 = temp;
edge_stream_character >> edg_char;
edge_stream_character >> edg_char;
if (v1 >= no_of_vertices || v2 >= no_of_vertices)
{
cerr << "Error: Vertex out of range.\n";
graph_builder.adjacency_list.clear();
break;
}
graph_builder.construct_edge({v1,v2});
}
}
if(flag_Entry == 1)
{
prev_choice = 'E';
break;
}
min_vertex_cover_algorithm(graph_builder);
prev_choice = 'E';
break;
}
}
}
}
catch (const char* err)
{
cerr << "Error:" << err << endl;
}
}
}
return 0;
}
int main(int argc, char **argv){
int ret;
pthread_t IO_thread;
ret = pthread_create(&IO_thread, NULL, IO_thread,NULL);
if(ret)
return 1;
pthread_join(IO_thread,NULL);
pthread_exit(NULL);
}
I am getting an error:
unknown type name 'Graph'
void min_vertex_cover_algorithm(Graph &graph_builder){
I am not able to find why this error is occuring. It will be very helpful if I get some solutions.
Just like you, the compiler will read from top to bottom. When it reaches the line:
void min_vertex_cover_algorithm(Graph &graph_builder){
It has to go, ok, lets use a Graph reference. It will look for the declaration of a Graph, which it cannot find, because you have declared (and defined) it below. To solve this, give the compiler a hint. Declare the Graph above the function with:
struct Graph;
void min_vertex_cover_algorithm(Graph &graph_builder){
Or simply move the whole struct definition above the function.

Using array from private access specifier

Here I have an array within the private section of my class which is unable to retain the values set in different members of the clas; during the fight sequence both of the values in the array equate to 0.
#include <iostream>
#include <string>
#include<math.h>
#include<cstdlib>
using namespace std;
class champions {
private:
int health_array[2] = { };
int attack_array[2] = { };
public:
void health_attack_set() {
int health_set{};
int attack_set{};
for (int i = 0; i < 2; i++) {
health_array[i] = health_set;
attack_array[i] = attack_set;
}
}
void fight_sequence(int random_champion, int random_opponent) {
cout << "FIGHT\n\n";
while (health_array[random_champion] > 0 or health_array[random_opponent] > 0) {
(health_array[random_opponent] -= attack_array[random_champion]);
if (health_array[random_opponent] <= 0) {
break;
}
(health_array[random_champion] -= attack_array[random_opponent]);
}
if (health_array[random_champion] > 0) {
cout << "CHAMPION 1 WINS!!!";
}
if (health_array[random_opponent] > 0) {
cout << "CHAMPION 2 WINS!!!";
}
if (health_array[random_champion] == 0 && health_array[random_opponent] == 0) {
cout << "NO ONE WINS!!";
}
}
void champion_1() {
health_attack_set();
health_array[0] = 400;
attack_array[0] = 150;
}
void champion_2() {
health_attack_set();
health_array[1] = 500;
attack_array[1] = 100;
}
};
int main() {
champions fight;
fight.fight_sequence(0, 1);
return 0;
}
I believe it may be a simple mistake but hard to spot; thank you for any help that is given.
I think your problems are coming from not understanding how to structure your code in the presence of classes and multiple objects. I have restructured your code below in a cleaner and more common way (it is not the only way to do it, but it is more typical). Hopefully there are not typos.
#include <iostream>
#include <string>
#include<math.h>
#include<cstdlib>
using namespace std;
class Champion{
public:
int health;
int attack;
Champion(int health_, int attack_) : health(health_), attack(attack_) {
}
};
void fight_sequence(Champion& champion, Champion& opponent) {
cout << "FIGHT\n\n";
while (champion.health > 0 || opponent.health > 0) {
(opponent.health -= champion.attack);
if (opponent.health <= 0) {
break;
}
(champion.health -= opponent.attack);
}
if (champion.health > 0) {
cout << "CHAMPION 1 WINS!!!";
}
if (opponent.health > 0) {
cout << "CHAMPION 2 WINS!!!";
}
if (champion.health == 0 && opponent.health == 0) {
cout << "NO ONE WINS!!";
}
}
int main() {
Champion champion_1(400, 150);
Champion champion_2(500, 100);
fight_sequence(champion_1, champion_2);
return 0;
}

Check if a string is a base 16 number

I've been trying to solve this task, but I had no positive results.
So, my task is to check if a string is a base 16 number.
example : s="1AB", it will show YES 427
Here is my code.
#include <iostream>
#include <string.h>
using namespace std;
int power (int a, int b)
{
if(b==1) return a;
else return a*power(a,b-1);
}
void conv(char s[],int &n)
{
int S=0,i,p=0;
for(i=n-1;i>=0;i--)
{
if(s[i]>='0' && s[i]<='9')
S+=(s[i]-48) * power(16,p); //ex:s[i]='1' ==> S+=(49-49)*...
else S+=(s[i]-55) * power(16,p); //s[i]='A' ==> S+=(65-55) *...
p++;
}
}
int main()
{
int n,i,k=0;
char s[255];
cin.get(s,255);
cin.get();
n=strlen(s);
for(i=0;i<n;i++)
{
if(strchr("0123456789ABCDEF",s[i])) k++;
}
if(k==0) cout<<"not in base 16";
else{
conv(s,n); cout<<s;}
return 0;
}
If you want almost clean solution, you can check mine:
#include <iostream>
using namespace std;
bool IsHex(string& in) {
for (char d : in) {
if (!isxdigit(d)) return false;
}
return true;
}
int Convert(string& in) {
int val = 0;
for (char d : in) {
val = val * 16 + (isdigit(d)? d - '0' : 10 + (isupper(d)? d - 'A' : d - 'a'));
}
return val;
}
int main() {
string in;
cin >> in;
if (!IsHex(in)) cout << "Not a correct hex number" << endl;
else cout << "YES " << Convert(in) << endl;
return 0;
}
And I have made some changes in your code to make it work. You can easily find out changes.
#include <iostream>
#include <string.h>
using namespace std;
int power (int a, int b)
{
if (b == 0) return 1;
if(b==1) return a;
else return a*power(a,b-1);
}
int conv(char s[],int &n)
{
int S=0,i,p=0;
for(i=n-1;i>=0;i--)
{
if(s[i]>='0' && s[i]<='9')
S+=(s[i]-48) * power(16,p); //ex:s[i]='1' ==> S+=(49-49)*...
else S+=(s[i]-55) * power(16,p); //s[i]='A' ==> S+=(65-55) *...
p++;
}
return S;
}
int main()
{
int n,i,k=0;
char s[255];
cin.get(s,255);
cin.get();
n=strlen(s);
for(i=0;i<n;i++)
{
if(!strchr("0123456789ABCDEF",s[i])) break;
}
if(i < n) cout<<"not in base 16";
else{
cout << conv(s,n) << endl;}
return 0;
}
You can just use std::isxdigit, for example:
#include <cctype>
#include <string>
#include <iostream>
bool IsThisStringAHexNumber(std::string const &str)
{
for (size_t i = 0, n = str.length(); i < n; ++i)
if (!std::isxdigit(str[i]))
return false;
return true;
}
int main()
{
std::cout << std::boolalpha << IsThisStringAHexNumber("298722h2jjh") << std::endl;
std::cout << std::boolalpha << IsThisStringAHexNumber("2abc66f") << std::endl;
return 0;
}
Prints:
false
true

Passing array values using pointer

I have two functions one is for file reading and another one for little sorting of numbers. With function read() I am reading file's each line and put each line into array. File looks like:
1
2
3
With function sort() I want to print only numbers with value greater than 1.
What is wrong: I got printed two arrays, but my sort array still printing all values, not only greater than 1.
My code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
class UZD
{
private:
int numLines;
int *value;
public:
UZD();
int * read();
int sort();
};
// =========================================================
UZD::UZD()
{
}
// =========================================================
int * UZD::read(){
ifstream myfile("stu.txt");
int value[20];
string line[20];
int i=0;
while(!myfile.eof() && i < 20) {
getline(myfile,line[i]);
++i;
}
numLines = i;
for (i=0; i < numLines; ++i) {
value[i] = atoi(line[i].c_str());
cout << i << ". " << value[i]<<'\n';
}
return value;
}
// =========================================================
int UZD::sort(){
int *p;
p = read();
int i;
if(p[i] > 1) {
cout << p <<'\n';
}
}
// =========================================================
int main() {
UZD wow;
wow.read();
wow.sort();
}
There are many issues in your code, the most obvious one is "return value" in the read() method. Value is a local array and will be gone once out of scope of read(). Also the design seems faulty. You are calling read() twice, once from the main() and again internally from sort().
I have written a working code, using vectors. Probably this is what you are expecting:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;
class UZD
{
private:
int numLines;
vector<int> value;
public:
UZD();
vector<int> & read();
void sort();
};
// =========================================================
UZD::UZD()
{
}
// =========================================================
vector<int> & UZD::read(){
ifstream myfile("stu.txt");
vector<string> line(20);
int i=0;
while(!myfile.eof() && i < 20) {
getline(myfile,line[i]);
++i;
}
numLines = i;
cout << "After reading file: " << endl;
for (i=0; i < numLines; ++i) {
value.push_back(atoi(line[i].c_str()));
cout << i << ". " << value[i]<<'\n';
}
return value;
}
// =========================================================
void UZD::sort(){
cout << "Inside sort()" << endl;
for(int i=0; i<value.size(); ++i){
if(value[i] > 1)
cout << value[i] << endl;
}
}
// =========================================================
int main() {
UZD wow;
wow.read();
wow.sort();
return 0;
}
I have kept the variable names same for clarity. Let me know if you don't get anything.
There are a lot of issues in your program; just to mention some of them:
In sort, you use variable i uninitialized, which is undefined behaviour (probably crashes); You write while(!myfile.eof()..., which is usually considered wrong (see this SO answer; The use of atoi is not recommended, as it is not safe if the parameter does not represent a number; You return a pointer to a local variable, which is destroyed one going out of scope; You declare member variables, but pass through local ones (e.g. value)...
See the following code which demonstrates the usage of int* and a vector<int>; hope it helps.
class UZD
{
private:
int numLines;
int *value = nullptr;
public:
~UZD() {
if (value)
delete value;
};
void read();
void print();
};
// =========================================================
void UZD::read(){
ifstream myfile("stu.txt");
value = new int[20];
int val;
numLines = 0;
while(numLines < 20 && myfile >> val) {
value[numLines] = val;
numLines++;
}
}
// =========================================================
void UZD::print(){
for (int i=0; i<numLines; i++)
cout << value[i] << endl;
}
class UZD_vector
{
private:
vector<int> values;
public:
void read();
void print();
};
// =========================================================
void UZD_vector::read(){
ifstream myfile("stu.txt");
int val;
while(myfile >> val) {
values.push_back(val);
}
}
// =========================================================
void UZD_vector::print(){
for (auto val : values)
cout << val << endl;
}
// =========================================================
int main() {
cout << "with int[]:" << endl;
UZD wow;
wow.read();
wow.print();
cout << "with vector:" << endl;
UZD wow_vector;
wow_vector.read();
wow_vector.print();
}
Here is your own code rectified, just in case you find vectors too difficult to learn (which should not be true, though)
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
class UZD
{
private:
int numLines;
int *value;
int num;
public:
UZD();
void read();
void sort();
};
// =========================================================
UZD::UZD():num(20)
{}
// =========================================================
void UZD::read(){
ifstream myfile("stu.txt");
value = new int[num];
string line[num];
int i=0;
while(!myfile.eof() && i < num) {
getline(myfile,line[i]);
++i;
}
numLines = i;
for (i=0; i < numLines; ++i) {
value[i] = atoi(line[i].c_str());
cout << i << ". " << value[i]<<'\n';
}
}
// =========================================================
void UZD::sort(){
cout << "After sorting: " << endl;
for (int i = 0; i < num; ++i) {
if(value[i] > 1)
cout << value[i] << endl;
}
}
// =========================================================
int main() {
UZD wow;
wow.read();
wow.sort();
return 0;
}

Crashing when objects are deleted

It's crashing at the very end of the main() function where it needs to delete the starters objects. The error message that pops up when I run the program says: Debug assertion failed! Expression: _BLOCK_IS_VALID(pHead->nBlockUse). How do i fix it from crashing when deleting the starters objects?
#include <iostream>
#include <fstream>
#include "olympic.h"
using namespace std;
ofstream csis;
int main() {
const int lanes = 4;
Ranker rank(lanes);
csis.open("csis.txt");
// First make a list of names and lane assignments.
Competitor* starters[lanes];
starters[0] = new Competitor("EmmyLou Harris", 1);
starters[1] = new Competitor("Nanci Griffith", 2);
starters[2] = new Competitor("Bonnie Raitt", 3);
starters[3] = new Competitor("Joni Mitchell", 4);
// The race is run; now assign a time to each person.
starters[0]->setTime((float)12.0);
starters[1]->setTime((float)12.8);
starters[2]->setTime((float)11.0);
starters[3]->setTime((float)10.3);
// Put everyone into the ranker.
for (int i = 0; i < lanes; i++)
rank.addList(starters[i]);
// Now print out the list to make sure its right.
cout << "Competitors by lane are:" << endl;
csis << "Competitors by lane are:" << endl;
for (int i = 1; i <= lanes; i++)
rank.getLane(i)->print();
// Finally, show how they finished.
cout << "Rankings by finish are:" << endl;
csis << "Rankings by finish are:" << endl;
for (int i = 1; i <= lanes; i++)
rank.getFinish(i)->print();
for (int i = 0; i < lanes; i++)
delete starters[i];
csis.close();
}
ranker.cpp:
#include "ranker.h"
#include "competitor.h"
#include <stdlib.h>
Ranker::Ranker(int lanes) {
athlete = new Competitor*[lanes];
numAthletes = 0;
maxAthletes = lanes;
}
int Ranker::addList(Competitor* starter) {
if (numAthletes < maxAthletes && starter != NULL) {
athlete[numAthletes] = starter;
numAthletes++;
return numAthletes;
}
else
return 0;
}
Competitor* Ranker::getLane(int lane) {
for (int i = 0; i < numAthletes; i++) {
if (athlete[i]->getLane() == lane) {
return athlete[i];
}
}
return NULL;
}
Competitor* Ranker::getFinish(int position) {
switch(position) {
case 1:
return athlete[3];
break;
case 2:
return athlete[2];
break;
case 3:
return athlete[1];
break;
case 4:
return athlete[0];
break;
}
return NULL;
}
int Ranker::getFilled() {
return numAthletes;
}
Ranker::~Ranker() {
delete [] athlete;
}
competitor.h:
#ifndef _COMPETITOR_H
#define _COMPETITOR_H
class Competitor {
private:
char* name;
int lane;
double time;
public:
Competitor(char* inputName, int inputLane);
Competitor();
void setTime(double inputTime);
char* getName();
int Competitor::getLane();
double getTime();
void print();
~Competitor();
};
#endif
competitor.cpp:
#include "competitor.h"
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
Competitor::Competitor(char* inputName, int inputLane) {
name = inputName;
lane = inputLane;
}
Competitor::Competitor() {
name = 0;
lane = 0;
time = 0;
}
void Competitor::setTime(double inputTime) {
time = inputTime;
}
char* Competitor::getName() {
return name;
}
int Competitor::getLane() {
return lane;
}
double Competitor::getTime() {
return time;
}
void Competitor::print() {
cout << setw(20) << name << setw(20) << lane << setw(20) << setprecision(4) << time << endl;
}
Competitor::~Competitor() {
delete [] name;
}
Call stack:
before crash: http://i.imgur.com/d4sKbKV.png
after crash: http://i.imgur.com/C5cXth9.png
After you've added Competitor class, it seems the problem is that you delete its name in Competitor's destructor. But you assign it from string literal which can't really be deleted. I'm sure the stack trace leading to assertion will prove that.
One way of solving the problem would be using std::string to store the name.
Problem is when deleting the char* value on destructor, which is assigned with const char instead new char. So i have slightly changed the constructor to copy the const char to new char.
Competitor::Competitor(char* inputName, int charlen, int inputLane)
{
name = new char[charlen + 1];
memcpy(name , inputName, charlen );
name [charlen] = '\0';
lane = inputLane;
}