I want to print strings from a struct in alphabetic order, and I have got help from the thread How to alphabetically sort strings?, for the sorting. My problem is that when i run the compiler i get a sorted output but it includes a name from another struct. My code looks like this:
#include <iostream>
#include <set>
#include <algorithm>
#include <string>
using namespace std;
const int antalShops = 2;
const int antalWorkers = 5;
struct employ {
string workerName; int workerAge;
};
struct theMall{
string shopName; string shopType; int shopSize;
employ workerName; employ workerAge;
};
// Declaration of the structs
theMall Shops[antalShops] = {
{"GameStop","toy", 250,},
{"Frandsen", "cloth", 300,},
};
employ Workers[antalWorkers] = {
{"Andrea valente", 41},
{"Giovanni Pirolli", 25},
{"Marco Cipolli", 33},
{"Jensine Jensen", 19},
{"Andrea Jensen", 99},
};
// Functions for sorting and printing names
void print(const string& item) {
cout << item << endl;
}
void PrintWorkers(employ Workers[]) {
set<string> sortedWorkers;
for(int i = 0; i <= antalWorkers; ++i) {
sortedWorkers.insert(Workers[i].workerName);
}
for_each(sortedWorkers.begin(), sortedWorkers.end(), &print);
}
void PrintShops(theMall Shops[]) {
set<string> sortedShops;
for (int i = 0; i <= antalShops; ++i) {
sortedShops.insert(Shops[i].shopName);
}
for_each(sortedShops.begin(), sortedShops.end(), &print);
}
int main(int argc, const char * argv[])
{
PrintShops(Shops);
}
So I have the structs with workers and shops, but when I i try printing the shop names with the PrintShops(Shops) function i get the output:
Andrea Valente
Frandsen
GameStop
I have been looking through the code, but i can't find where the mistake is, anyone can see the error?
You go outside the bounds of the arrays in your loops
for (int i = 0; i <= antalShops; ++i) {
// Problem here ^^
The above loop will loop over indexes 0, 1 and 2, which is one to many for a two-entry array. This will lead to undefined behavior.
You have the same problem with the other sorting loop.
Related
I am creating a program that receives a value in multiset in the form of vector<multisetvp; and stores it in multiset inside the vector when the number of it becomes five. If you store values from 1 to 10, when you print out vector,
1 2 3 4 5
6 7 8 9 10
I want it to come out like this.
However, it is difficult to output the value stored in multiset inside the vector. Ask for help in how to solve this problem.
I also tried to output the value of 'sp' using overlapping 'range-based for statements', but it ended up outputting only one multiset of vector. I want to store and output multisets with up to five elements in the vector.
#include <iostream>
#include <set>
#include <vector>
#include <array>
using namespace std;
class MyCharector {
vector<multiset<char>> vp;
vector<multiset<char>>::iterator vit;
multiset<char>* sp;
multiset<char>::iterator sit;
public:
~MyCharector() { }
void ininven(multiset<char> s) {
vp.push_back(s);
}
void getItem(char* item) {
sp = new multiset<char>;
for (int i = 0; i < 10; i++) {
sp->insert(item[i]);
if (sp->size() == 5) {
ininven(*sp);
}
}
delete sp;
}
void dropItem() { // is not use
vit = vp.begin();
vit = vp.erase(vit);
}
void showItem() {
for (vit = vp.begin(); vit != vp.end(); vit++) {
// problems.....
}
}
};
int main(int argc, const char* argv[]) {
MyCharector my;
array<char,10> item = { 'a','a','e','d','g','f','c','c','h','b' };
my.getItem(item.data());
my.showItem();
return 0;
}
Of course you can make it work with iterators but what's wrong with simple range based loops?
for (const auto& ms : vp)
for (char c : ms)
cout << c;
Also why use new and delete in getItem? And why declare class variables when you should use local variables?
void getItem(char* item) {
multiset<char> sp;
for (int i = 0; i < 10; i++) {
sp.insert(item[i]);
if (sp.size() == 5) {
ininven(sp);
}
}
}
sp doesn't need to be a pointer, and it should be a local variable.
EDIT
Also I think getItem has a bug. I'm guessing that you want a new multiset every five character, but that's not what the code does. Maybe this is what you want
void getItem(char* item) {
multiset<char> sp;
for (int i = 0; i < 10; i++) {
sp.insert(item[i]);
if (sp.size() == 5) {
ininven(sp);
sp.clear(); // start again
}
}
}
#include <iostream>
#include <string.h>
using namespace std;
class sorting
{
private:
char str[10];
public:
sorting() {
int i;
for(i=0;i<10;i++) {
cin>>str[i];
}
}
void sort() {
int i,j;
char temp;
for(i=0;i<10;i++) {
for(j=i+1;j<10;j++) {
if(strcmp(str[j],str[j+1])>0) {
strcpy(temp,str[j]);
strcpy(str[j],str[j+1]);
strcpy(str[j+1],temp);
}
}
}
for(i=0;i<10;i++) {
cout<<str[i];
cout<<"\n";
}
}
};
int main() {
sorting s1;
cout<<s1.sort();
return 0;
}
This is a code I have written to sort strings using constructors. It gives me error in the if condition of the code where I have used strcmp. Please review this for I could not get the desired output and it gives me errors.
Problem 1
Like someone already pointed out, you cant use strcopy on chars. If you want to create a string array i would suggest using either char** or std::string*.
Problem 2
In your nested loop you will get an index out of bounds error, due to the fact that once i reaches a value of 8, j will be 9, which means that when you try to access str[j+1] which evaluates to str[10], you will get said error.
I'm trying to write a function that takes an array of structs and will sort the elements of the array alphabetically by accessing the first data member. I'm struggling to get the code to distinguish between when I'm referring to a data member versus initializing the size of an array. For example, the following code
void selectionSort(struct A[], int size)
{
int mindex;
for (int ct1 = 0; ct1 < size - 1; ct1++)
{
mindex = ct1;
for (int ct2 = ct1 + 1; ct2 < size; ct2++)
if (A[ct2].state < A[mindex].state)
mindex = ct2;
swap(A[mindex], A[ct1]);
}
}
complains that ct2 is not constant, when I'm clearly using it as an index. How would I get this to run correctly? That is, how can I get it to compare data members in their respective indices rather than think I'm initializing the size of a struct variable?
Edit The error message I am receiving is expression must have a constant value for the variable ct2.
I think you might have a problem with how you're creating your function. Usually, when you declare an array of structs it looks like this.
struct Student {
int uid;
string name;
};
Student studentArry[3];
You would use 'Student' or the name of your struct to initialize your array. For example, int arr[10] is an integer array of size 10 while Student arr[10] is a student array of size 10.
One other side note, if you're trying to create a function that is passed a struct you have to initialize the struct before you define the function. This code will work because the struct was declared before the function was.
#include <iostream>
using namespace std;
struct Student {
int uid;
string name;
};
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
The code below will not because the print function doesn't know what type student is.
#include <iostream>
using namespace std;
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
struct Student {
int uid;
string name;
};
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
So, all in all, I think you need to change how you're creating the parameter for the function and possible where you're declaring your struct.
Im trying to write a class that stores an id and a value in an container class.
Im using an nested class as my data structure.
When im compiling the code sometimes it prints perfectly, sometimes it prints nothing and sometimes it prints half of the data then stops.
When i debug the code the same weird behavior occours, when it fails during debug it throws an error "Map.exe has triggered a breakpoint.", the Error occours in the print method when im using cout.
cmap.h
#pragma once
class CMap
{
public:
CMap();
~CMap();
CMap& Add(int id, int value);
void print() const;
private:
class container
{
public:
~container();
int container_id = 0;
int container_value = 0;
};
container* p_komp_;
int dim_ = -1;
void resize();
};
cmap.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
CMap::CMap()
{
p_komp_ = new container[0];
}
CMap::~CMap()
{
p_komp_ = nullptr;
cout << "destroy cmap";
}
CMap& CMap::Add(int id, int value)
{
resize();
p_komp_[dim_].container_id = id;
p_komp_[dim_].container_value = value;
return *this;
}
void CMap::resize()
{
container* temp_array = new container[++dim_];
if (dim_ == 0)
{
temp_array[0].container_id = p_komp_[0].container_id;
temp_array[0].container_value = p_komp_[0].container_value;
}
for (unsigned i = 0; i < dim_; i++)
{
temp_array[i].container_id = p_komp_[i].container_id;
temp_array[i].container_value = p_komp_[i].container_value;
}
p_komp_ = temp_array;
}
void CMap::print() const
{
for (unsigned i = 0; i <= dim_; i++)
{
cout << p_komp_[i].container_id;
cout << p_komp_[i].container_value;
}
}
CMap::container::~container()
{
cout << "destruct container";
}
Map.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
void main(void)
{
CMap m2;
m2.Add(1, 7);
m2.Add(3, 5);
m2.print();
}
These two things are a possible reason for your problem:
int dim_ = -1;
and
container* temp_array = new container[++dim_];
When you allocate, you increase dim_ from -1 to 0. That is you create a zero-sized "array", where every indexing into it will be out of bounds and lead to undefined behavior.
You also have memory leaks since you never delete[] what you new[]. I didn't look for more problems, but there probably a more.
And an "array" (created at compile-time or through new[]) will have indexes from 0 to size - 1 (inclusive). You seem to think that the "size" you provide is the top index. It's not, it's the number of elements.
It seems to me that you might need to take a few steps back, get a couple of good books to read, and almost start over.
I have the following C++ code for practising sequence list and it passed the complier. However, when I try to run it, it returns Segmentation fault. Please help!! Thanks a lot.
main.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
int main() {
SeqList seq;
string vv[] = {"a", "b", "c", "d"};
for (int i = 0; i< 4; i++) {
seq.addElement(vv[i], i);
}
string* v = seq.getSeq();
for (int i=0; i<seq.getSeqSize(); i++) {
cout << v[i] <<endl;
}
return 0;
}
SeqList.h
#include<iostream>
#include<string>
using namespace std;
class SeqList {
private:
string seq[];
int size;
public:
void addElement(string, int);
void delElement(string, int);
string* getSeq();
int getSeqSize();
};
SeqList.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
string seq[100];
int size = 0;
string* SeqList::getSeq(){
return seq;
};
int SeqList::getSeqSize(){
return size;
};
void SeqList::addElement(string str, int pos) {
int i;
for (i = size; i > pos; i--) {
seq[i] = seq[i-1];
}
seq[i-1] = str;
size++;
};
Your segfault is happening because you're trying to access seq[i-1] in addElement when i = 0. This tries to access the memory outside of seq which causes a segfault. Try using seq[i] and seq[i+1] instead of seq[i-1] and seq[i], though you'll have to make sure you never call that code with more than 99 values or you'll run into a similar problem where the program tries to access memory past the end of seq.
Also, in SeqList.cpp
string seq[100];
int size = 0;
These lines are creating new variables, when it looks like you're trying to change the values you made in SeqList.h. To change those private values in your class you should either use a constructor or other function to initialize the values.