Printing out table column names - c++

I currently have this function to print out every rows of my tables
static int callback(void *NotUsed, int argc, char **argv, char **szColName)
{
for(int i = 0; i < argc; i++)
{
cout.width(17); cout << left << argv[i];
}
std::cout << "\n";
return 0;
}
How do I print out szColName, such that it only appear once on top, and not multiple occurences of it?
Tried this:
static int callback(void *NotUsed, int argc, char **argv, char **szColName)
{
int n = sizeof(szColName) / sizeof(szColName[0]);
for (int i = 0; i < n; i++)
{
cout.width(17); cout << left << szColName[i];
}
printf("\n");
for(int i = 0; i < argc; i++)
{
cout.width(17); cout << left << argv[i];
}
std::cout << "\n";
return 0;
}
But it outputs everytime after a outputting the row values

You might want to declare a static bool inside callback to record whether it has already printed out the column names. Or, if you want to be able to reset it...
such as:
static bool firstline = true;
static int callback(void *NotUsed, int argc, char **argv, char **szColName)
{
if (firstline){
int n = sizeof(szColName) / sizeof(szColName[0]);//this is incorrect but fixing
// it requires changing the prototype.
//See the comments below
for (int i = 0; i < n; i++)
{
cout.width(17); cout << szColName[i] << left;
}
printf("\n");
firstline=false;
}
for(int i = 0; i < argc; i++)
{
cout.width(17); cout << argv[i] << left;
}
std::cout << "\n";
return 0;
}
int main(){
for(int x=0;x<10;++x)callback( ... , ... , ... ); // give whatever argument you need to give
firstline = true; //reset the variable so that next time you call it, the col names will appear
for(int x=0;x<10;++x)callback(...,...,...);// now the col names will appear again.
}
I assume that what you provide would print out the rows and the column names correctly. I only added a variable to check if printing column names are needed.

Related

Problem using std::sort with custom class

Doing hackerrank problem "Attending Workshops" https://www.hackerrank.com/challenges/attending-workshops/problem
I have the problem that I can't sort my vector. I tried with a lambda (in commentary) and then by overloading the operator >.
My vector never turn out to be sorted. Can you help me find what I did wrong. Here is my code:
#include<bits/stdc++.h>
using namespace std;
//*************ABOVE IS LOCKED CODE BY HACKERRANK****************;
//Define the structs Workshops and Available_Workshops.
//Implement the functions initialize and CalculateMaxWorkshops
struct Workshop
{
int startTime;
int endTime;
int duration;
Workshop(){}
Workshop(int pStartTime, int pDuration)
:startTime(pStartTime), duration(pDuration)
{
endTime = startTime + duration;
}
bool operator < (const Workshop &other) const
{
cout << "trace inside operator never showing up" << endl;
return endTime < other.endTime;
}
};
struct Available_Workshops
{
int nbWorkshop;
vector<Workshop> workshops;
Available_Workshops(int *start_times, int *durations, int n)
:nbWorkshop(n)
{
workshops.reserve(n);
for(int i = 0; i < n; ++i)
{
workshops[i] = Workshop(start_times[i], durations[i]);
}
}
};
Available_Workshops *initialize(int *start_time, int *duration, int n)
{
return new Available_Workshops(start_time, duration, n);
}
int CalculateMaxWorkshops(Available_Workshops *avai_work_ptr)
{
//The two for loops are just there to trace the content of avai_work_ptr->nbWorkshop to validate sorting...
for(int i = 0; i < avai_work_ptr->nbWorkshop; ++i)
cout << avai_work_ptr->workshops[i].startTime << " " << avai_work_ptr->workshops[i].endTime << endl;
std::sort(avai_work_ptr->workshops.begin(), avai_work_ptr->workshops.end());//, [](const Workshop &a, const Workshop &b){cout << "compar"; return a.startTime < b.startTime;});
for(int i = 0; i < avai_work_ptr->nbWorkshop; ++i)
cout << avai_work_ptr->workshops[i].startTime << " " << avai_work_ptr->workshops[i].endTime << endl;
int maxWorkshop = 0;
//Chunk of code removed because it is not related to the sort problem...
//...
return maxWorkshop;
}
//*************BELOW IS LOCKED CODE BY HACKERRANK****************;
int main(int argc, char *argv[]) {
int n; // number of workshops
cin >> n;
// create arrays of unknown size n
int* start_time = new int[n];
int* duration = new int[n];
for(int i=0; i < n; i++){
cin >> start_time[i];
}
for(int i = 0; i < n; i++){
cin >> duration[i];
}
Available_Workshops * ptr;
ptr = initialize(start_time,duration, n);
cout << CalculateMaxWorkshops(ptr) << endl;
return 0;
}
Thank you.
workshops.reserve(n);
is wrong. It just do allocation and not inclease the number of valid elements, so the end() iterator will still be the top of the array.
You should use
workshops.resize(n);
instead.

I need to display "Monday" with left justified and the highest columns appears in first row in descending order

should be like this output:
Monday
onday
nday
day
ay
y
what I have so far:
#include <iostream>
using namespace std;
int main () {
char *weekDays[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
for (int i=0;i<7;i++){
cout << weekDays[0][i] << endl;
}
return 0;
}
output:
M
o
n
d
a
y
Im on mobile and tired but sth. like this should work:
int main(){recPrint(0);}
void recPrint(int level){
char mon[] = "Monday";
for(int i=level; i<strlen(mon); i++){
std::cout << mon[i];
}
std::cout << std::endl;
recPrint(++level);
}
add another parameter char dayOfTheWeek[] and you can call it with whatever you want.
Try this
#include <iostream>
using namespace std;
void display(char s[])
{
int n = strlen(s);
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++)
{
cout << s[j];
}
cout << endl;
}
}
int main () {
char *weekDays[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
display(weekDays[0]);
}

Dynamic ASCII Box with Numbers Inside

Having a problem in making a dynamic box using these set of ASCII codes. I'm really lost on what to do. This dynamic box also has numbers inside them.
I already tried making loops inside loops to adjust the box's size.
int main(){
char asciis[] = {'\xDA','\xB3','\xC3','\xC0','\x20','\xC4','\xC5','\xC1','\xBF','\xB4','\xD9', '\xC2'};
int box size = (n*2)+1;
char box[box size][box size]; //set the size of the box
//set a in all coordinates
/*for (int r = 0; r < n; r++){
for (int c = 0; c < n; c++){
box[r][c] = 'a';
}
}*/
for (int r = 0; r < n; r++){
for (int c = 0; c < n; c++){
for (int boxrow = 0; boxrow < box size; boxrow++){
for (int boxcol = 0; boxcol < box size; boxcol++){
//conditions
}
}
}
cout << endl;
}
}
This is the output I'm trying to create:
https://i.imgur.com/YRgMlaJ.png
Don't mind those numbers, I was just mapping the array.
I'm sure there's a simpler solution, but off the top of my head:
#include <iostream>
using namespace std;
enum BoxParts {
kLeftUpper = '\xDA',
kVertical = '\xB3',
kLeftBreak = '\xC3',
kLeftLower = '\xC0',
kEmpty = '\x20',
kHorizontal = '\xC4',
kIntersection = '\xC5',
kBottomBreak = '\xC1',
kRightUpper = '\xBF',
kRightBreak = '\xB4',
kRightLower = '\xD9',
kTopBreak = '\xC2',
kCount = 12
};
void drawLine(const int cellCount, const int cellWidth, const char left, const char divider, const char contents, const char right)
{
cout << left;
for (int i = 1; i < cellCount * cellWidth; ++i)
{
if (0 == i % cellWidth)
cout << divider;
else
cout << contents;
}
cout << right << endl;
}
void drawBox(const int cellCount, const int cellWidth, const int cellHeight)
{
// top
drawLine(cellCount, cellWidth, kLeftUpper, kTopBreak, kHorizontal, kRightUpper);
for (int i = 1; i < cellCount * cellHeight; ++i)
{
if (0 == i % cellHeight)
drawLine(cellCount, cellWidth, kLeftBreak, kIntersection, kHorizontal, kRightBreak);
else
drawLine(cellCount, cellWidth, kVertical, kVertical, ' ', kVertical);
}
// bottom
drawLine(cellCount, cellWidth, kLeftLower, kBottomBreak, kHorizontal, kRightLower);
}
int main(int argc, char** argv) {
const int n = 4;
drawBox(n, 10, 5);
getchar();
return 0;
}
Produces:

Seg fault is eliminated when copying char** -- why is this?

class uid
{
public:
char id[6] = {'0','0','0','0','0','0'};
uid() {}
~uid() {}
inline void recursive(int x)
{
if(':' == id[x])
{
id[x] = '0';
++id[--x];
recursive(x);
}
}
char* operator++()
{
++id[5];
recursive(5);
return id;
}
void write(char* pchar) const
{
for(int i = 0; i < 6; ++i)
pchar[i] = id[i];
}
};
using namespace std;
int main(int argc, char** argv)
{
const int MAX = 5000000;
uid c;
char** arr = new char*[MAX];
//char** it = arr;
//loop 1
for(int i = 0; i < MAX; ++i)
arr[i] = new char[6];
cout << "allocated" << endl;
//loop 2
for(int i = 0; i < MAX; ++i)
{
++c;
c.write(arr[i]);
}
cout << "data written" << endl;
for(int i = 0; i < MAX; ++i)
delete[] arr[i];
cout << "deleting arr" << endl;
delete[] arr;
return 0;
}
Running this will cause a seg fault in loop 2 when i == 999999 -- However, when adding the line:
char** it = arr;
The seg fault disappears -- does anyone have any ideas of why this happens?
Thanks
As soon as you go past 999,999 you are writing to memory not owned by c. Declaring it changes the memory map enough that there is no immediate segfault, but the code is still not correct, and any other small change might bring back the fault.
Here's how to fix it:
inline void recursive(int x)
{
if(':' == id[x])
{
id[x] = '0';
if (x) { // <-- added this
++id[--x];
recursive(x);
}
}
}
Now overflow will wrap around to 000000 instead of creating a 7 digit number in a space not big enough to hold it.

c++ function can not call twice

I have this code. From main function i twice call sportPrisevinners function and if it is first call of this function it works correctly and I recive correct result, but when i call it second time I recive incorrect result even I pass this function with same arguments. Please help me to solve this problem while it doesn`t make me crasy.
const char* countries[] = {"ru", "gb", "us", "uk", "ch", "de"};
const int countriesCount = 6;
const char* sports[] = {"runing", "swiming", "baseball", "football", "jumping", "kerling"};
const int sportsCount = 6;
enum {
Empty = 0,
Bronse,
Silver,
Gold
};
struct member {
char sport[9];
char country[3];
int points;
int medal;
};
struct members {
member* list;
int count;
};
string medalToStr(int medal)
{
switch (medal) {
case Gold:
return "Gold";
case Silver:
return "Silver";
case Bronse:
return "Bronse";
default:
return "Empty";
}
}
void printMembers(members &list)
{
for (int i = 0; i < list.count ; i++)
cout << /*i << " " <<*/ medalToStr(list.list[i].medal) << " in "
<< list.list[i].sport << " with " << list.list[i].points
<< " from " << list.list[i].country << endl;
}
void generate()
{
ofstream file("members.dat", ios::binary|ios::trunc);
member temp;
for (int i = 0; i < sportsCount ; i++)
for (int j = 0; j < countriesCount ; j++)
{
int count = rand()%5+5;
for (int k = 0; k < count ; k++)
{
strcpy(&temp.sport[0], sports[i]);
strcpy(&temp.country[0], countries[j]);
temp.points = rand()%100;
temp.medal = Empty;
file.write((char*)&temp, sizeof(member));
}
}
file.close();
}
members sportPrisevinners(const char* sport)
{
//reading
ifstream file("members.dat", ios::binary);
member* loaded = new member[60];
int pos = 0;
while (!file.eof())
{
member temp;
file.read((char*)&temp, sizeof(member));
static bool reading = false;
if (strncmp(&temp.sport[0], sport, strlen(sport))==0) {
reading = true;
loaded[pos++] = temp;
} else if (reading) {
break;
}
}
file.close();
//sorting
int count = 3;
for (int i = 0; i < pos-1 ; i++)
{
for (int j = i+1; j < pos ; j++)
if (loaded[i].points<loaded[j].points)
{
member temp = loaded[i];
loaded[i] = loaded[j];
loaded[j] = temp;
}
if (i<count) {
static int last = -1;
if (loaded[i].points==last)
count++;
loaded[i].medal = count-i;
last = loaded[i].points;
} else break;
}
//returning
members result;
result.list = new member[count];
memcpy(result.list, loaded, count*sizeof(member));
/*for (int i = 0; i < count; i++)
result.list[i] = loaded[i];*/
result.count = count;
delete[] loaded;
return result;
}
int main(int /*argc*/, char */*argv*/[])
{
srand(time(0));
generate();
members r = sportPrisevinners(sports[4]);
printMembers(r);
delete[] r.list;
members l = sportPrisevinners(sports[5]);
printMembers(l);
delete[] l.list;
system("pause");
return 0;
}
I suspect it's the static local variables in your function. They won't have the same values on each call to the function, and this could affect the results. The initialization of these variables is performed just once - the first time they come into scope - so each subsequent time the function is called, you pick up the values these variables had last time the function ran.