std::cout is not printing - c++

When I print out using std::cout, it doesn't print anything to the terminal:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
std::string multiplystr(std::string string, int mult) {
for (int i = 1; i < mult; i++) {
string = string + string;
}
return string;
}
class entry {
public:
entry(int width) {
int frameWidth = width;
}
int frameWidth;
std::string framechar = "-";
std::string frame = multiplystr(framechar, (frameWidth + 4));
std::string justout = frame + '\n';
};
int main() {
entry x1(15);
std::string out1 = x1.frame;
std::cout.flush();
cout << "out1" << std::endl;
}
However, if I delete everything except the print statement, it prints properly. Do you know why it does this?
I also used std::flush and it does not work.

Your code has undefined behavior, so literally anything could happen 1.
In your entry class, the constructor body is assigning its input width value to a local variable named frameWidth which shadows the class member of the same name. As such, the frameWidth member is never initialized.
You are then passing the frameWidth member to the mult parameter of multiplystr() when initializing the frame member. The frame member is initialized before the constructor body begins running, so even if you fixed the constructor body to get rid of the local variable and assign the width value to the frameWidth member correctly, by then it is too late, the damage has already been done.
1: In my test, when I run the code, I get a runtime error before the print statement is reached, because mult ends up being a very large value that causes the loop to blow up available memory.
To fix that, you need to initialize the frameWidth member in the constructor's initialization list instead of the constructor body. The initialization list will initialize frameWidth before the frame member is initialized, and thus before multiplystr() is called.
Try this:
#include <iostream>
#include <vector>
#include <string>
std::string multiplystr(std::string s, int mult) {
for (int i = 1; i < mult; i++) {
s += s;
}
return s;
}
class entry {
public:
entry(int width) : frameWidth(width) {}
int frameWidth;
std::string framechar = "-";
std::string frame = multiplystr(framechar, (frameWidth + 4));
std::string justout = frame + '\n';
};
int main() {
entry x1(15);
std::string out1 = x1.frame;
std::cout << "out1 = " << out1 << std::endl;
}
Online Demo

Related

Uninitialised local variable from class

When I'm trying to access classes public variable (in this case trying to input text row) it shows that it's uninitialized. However, I declared it in class as a public variable.
I know that's some dummy mistake, but can't find it :D
#include <iostream>
#include <conio.h>
using namespace std;
class stringlength {
private:
int lengt;
public:
char * row;
int len()
{
for (int i = 0, lengt = 0; (*(row + i) != '\0'); i++, lengt++) {}
return lengt;
}
};
int main()
{
stringlength test;
cout << "Enter a string:";
cin >> test.row;
cout << "Length is: " << test.len();
_getch();
}
This program is expected to give a length of the inputted row (like strlen function)
Error is:
Error C4700 uninitialized local variable 'test' used
Thanks for help ;)
Declaring the variable does not mean that it's initialized.
Initialize it in a constructor, or just char * row = nullptr; (if 0 is the intended initialization).
Same for all the variables that you have which have no constructors.
Edit: in this specific case you need to initialize to a new pointer char * row = new char[...]

C++: Setters and Getters for Arrays

I am struggling to find the correct format for initializing a (private) array within a class and getting/setting the values from outside the class.
My code is semi-functional, but feels awkward in incorrectly formatted.
It is returning only the first element of the array, I want it to return all the contents. Read code comments for additional details.
Note: This is (a very small part of) a project I am working on for school -- an array must be used, not a vector or list.
student.h
class Student {
public:
// Upon researching my issue, I read suggestions on passing pointers for arrays:
void SetDaysToCompleteCourse(int* daysToCompleteCourse[3]);
int* GetDaysToCompleteCourse(); // Ditto # above comment.
private:
int daysToCompleteCourse[3];
student.cpp
#include "student.h"
void Student::SetDaysToCompleteCourse(int* daysToCompleteCourse) {
// this->daysToCompleteCourse = daysToCompleteCourse; returns error (expression must be a modifiable lvalue)
// Feels wrong, probably is wrong:
this->daysToCompleteCourse[0] = daysToCompleteCourse[0];
this->daysToCompleteCourse[1] = daysToCompleteCourse[1];
this->daysToCompleteCourse[2] = daysToCompleteCourse[2];
}
int* Student::GetDaysToCompleteCourse() {
return daysToCompleteCourse;
}
ConsoleApplication1.cpp
#include "pch.h"
#include <iostream>
#include "student.h"
int main()
{
Student student;
int daysToCompleteCourse[3] = { 1, 2, 3 };
int* ptr = daysToCompleteCourse;
student.SetDaysToCompleteCourse(ptr);
std::cout << *student.GetDaysToCompleteCourse(); // returns first element of the array (1).
}
I gave this my best shot, but I think I need a nudge in the right direction.
Any tips here would be greatly appreciated.
I would say:
// student.h
class Student
{
public:
// If you can, don't use numbers:
// you have a 3 on the variable,
// a 3 on the function, etc.
// Use a #define on C or a static const on C++
static const int SIZE= 3;
// You can also use it outside the class as Student::SIZE
public:
void SetDaysToCompleteCourse(int* daysToCompleteCourse);
// The consts are for "correctness"
// const int* means "don't modify this data" (you have a setter for that)
// the second const means: this function doesn't modify the student
// whithout the const, student.GetDaysToCompleteCourse()[100]= 1 is
// "legal" C++ to the eyes of the compiler
const int* GetDaysToCompleteCourse() const; // Ditto # above comment.
Student()
{
// Always initialize variables
for (int i= 0; i < SIZE; i++) {
daysToCompleteCourse[i]= 0;
}
}
private:
int daysToCompleteCourse[SIZE];
// On GCC, you can do
//int daysToCompleteCourse[SIZE]{};
// Which will allow you not to specify it on the constructor
};
// student.cpp
void Student::SetDaysToCompleteCourse(int* newDaysToCompleteCourse)
{
// It's not wrong, just that
// this->daysToCompleteCourse[0] = daysToCompleteCourse[0];
// use another name like newDaysToCompleteCourse and then you can suppress this->
// And use a for loop
for (int i= 0; i < SIZE; i++) {
daysToCompleteCourse[i]= newDaysToCompleteCourse[i];
}
}
const int* Student::GetDaysToCompleteCourse() const
{
return daysToCompleteCourse;
}
// main.cpp
#include <iostream>
std::ostream& operator<<(std::ostream& stream, const Student& student)
{
const int* toShow= student.GetDaysToCompleteCourse();
for (int i= 0; i < Student::SIZE; i++) {
stream << toShow[i] << ' ';
}
return stream;
}
int main()
{
Student student;
int daysToCompleteCourse[3] = { 1, 2, 3 };
// You don't need this
//int* ptr = daysToCompleteCourse;
//student.SetDaysToCompleteCourse(ptr);
//You can just do:
student.SetDaysToCompleteCourse(daysToCompleteCourse);
// On C++ int* is "a pointer to an int"
// It doesn't specify how many of them
// Arrays are represented just by the pointer to the first element
// It's the FASTEST and CHEAPEST way... but you need the SIZE
const int* toShow= student.GetDaysToCompleteCourse();
for (int i= 0; i < Student::SIZE; i++) {
std::cout << toShow[i] << ' ';
// Also works:
//std::cout << student.GetDaysToCompleteCourse()[i] << ' ';
}
std::cout << std::endl;
// Or you can do: (because we defined operator<< for a ostream and a Student)
std::cout << student << std::endl;
}
You can check out it live here: https://ideone.com/DeJ2Nt

How to fill a String inside an array of structures within a structure in C++

So I have a structure called fastarray which contains a poiner to another structure called token_det. My problem is trying to fill a char array inside the array of structs fails mid way through and gives a error message as "The exception unknown software exception (0x0000417) occured in the application at location 0x78b2ae6e". I tried increasing the size of the char array using malloc but the string concat function keeps failing after concatinating a few strings. Below is a example of the code:
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <iostream.h>
using namespace std;
#define MAX_TOKENS 300000
struct token_det
{
int token;
std::string data;
char mdepth[300];
};
typedef struct fastarray
{
token_det *td; //MAX_TOKENS
}FASTARRAY;
int main()
{
printf("inside main\n");
int lv_ret = 0;
int count = 0;
char log[50] = {""};
int wtoken = 0;
FASTARRAY *f_array = NULL;
f_array = (FASTARRAY *)malloc(sizeof(FASTARRAY));
f_array->td = NULL;
f_array->td = (token_det *)malloc(MAX_TOKENS * sizeof(token_det));
printf("after malloc\n");
memset(f_array, 0, sizeof(f_array));
memset(f_array->td, 0, sizeof(f_array->td));
int x=0;
while(x<=10000)
{
printf("inside while");
f_array->td[x].data = "104,";
f_array->td[x].data.append("stasimorphy");
f_array->td[x].data.append(",");
f_array->td[x].data.append("psychognosy");
f_array->td[x].data.append(",");
f_array->td[x].data.append("whoever");
f_array->td[x].data.append(",");
x++;
sprintf_s(log,sizeof(log),"Data for x-%d = %s\n",x,f_array->td[x].data);
printf(log);
}
free(f_array->td);
free(f_array);
printf("after while\n");
return 0;
}
Explanation of what I was doing and why
When I tried to understand what you wanted to do there I've had no problem except for the parts in which you're using memset. With memset(f_array, 0, sizeof(f_array)); you're explicitly setting the f_array to point to 0 in the memory which was constantly throwing exceptions for me.
As I've never really been a friend of malloc I've been using C++ syntax as follows:
For allocating a single instance I'd use FASTARRAY *f_array = new fastarray;. You can read up on why using new instead of malloc is favorable in C++ here.
In the same way I've been using C++ syntax for allocating the dynamic array f_array->td = new token_det[MAX_TOKENS]; A Q&A about that topic for reference can be found here.
For filling the data string inside the dynamic array's struct I've been using the += syntax as it's easier to read, in my opinion. Accessing the element inside the f_array has been achieved using (*(f_array->td + x)).data += "stasimorphy";
You can try my solution online here.
Code Dump
I tried to change as little as possible to make it work.
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
#define MAX_TOKENS 300000
struct token_det
{
int token;
std::string data;
char mdepth[300];
};
typedef struct fastarray
{
token_det *td; //MAX_TOKENS
}FASTARRAY;
int main()
{
std::cout << "inside main\n";
int lv_ret = 0;
int count = 0;
char log[50] = { "" };
int wtoken = 0;
FASTARRAY *f_array = new fastarray;
f_array->td = new token_det[MAX_TOKENS];
std::cout << "after malloc\n";
int x = 0;
while (x <= 10000)
{
std::cout << "inside while";
std::stringstream log;
(*(f_array->td + x)).data = "104,";
(*(f_array->td + x)).data += "stasimorphy";
(*(f_array->td + x)).data += ",";
(*(f_array->td + x)).data += "psychognosy";
(*(f_array->td + x)).data += ",";
(*(f_array->td + x)).data += "whoever";
(*(f_array->td + x)).data += ",";
log << "Data for x-" << x << " = " << (f_array->td + x)->data << std::endl;
std::cout << log.str();
x++;
}
delete[] f_array->td;
free(f_array);
std::cout << "after while\n";
return 0;
}

C++ Undeclared Identifier on Object creation

So I am new to c++, coming from C#. This is giving me several errors when compiling, which all seem to relate to this object declaration. Anyone able to show me the right way to do this?
I get an undeclared identifier where i declare tri(sideLength).
I have used this as a reference for object declaration, but it doesn't seem to be helping me.
Thanks.
#include <iostream> // Provides cout
#include <iomanip> // Provides setw function for setting output width
#include <cstdlib> // Provides EXIT_SUCCESS
#include <cassert> // Provides assert function
#include <stdexcept>
#include <math.h>
using namespace std; // Allows all standard library items to be used
void setup_cout_fractions(int fraction_digits)
// Precondition: fraction_digits is not negative.
// Postcondition: All double or float numbers printed to cout will now be
// rounded to the specified digits on the right of the decimal.
{
assert(fraction_digits > 0);
cout.precision(fraction_digits);
cout.setf(ios::fixed, ios::floatfield);
if (fraction_digits == 0)
cout.unsetf(ios::showpoint);
else
cout.setf(ios::showpoint);
}
int main()
{
const int MAX_SIDE_LENGTH = 6;
const int INITIAL_LENGTH = 1;
const int DIGITS = 4;
const int ARRAY_SIZE = 6;
// Set up the output for fractions and print the table headings.
setup_cout_fractions(DIGITS);
// Each iteration of the loop prints one line of the table.
for (int sideLength = 0; sideLength < MAX_SIDE_LENGTH; sideLength += 1)
{
EquilateralTriangle tri(sideLength);
//Square sq(sideLength);
//Pentagon_Reg pent(sideLength);
//Hexagon_Reg hex(sideLength);
//Heptagon_Reg hept(sideLength);
//Octagon_Reg octa(sideLength);
cout << "Type: " << tri.Name() << "has area: " << tri.Area() << " with SideLength = " << sideLength;
}
return EXIT_SUCCESS;
}
//Template
class GeometricFigure
{
public:
GeometricFigure() { }
double SideLength;
virtual double Area() { return 0; };
virtual char* Name() { return ""; };
};
class EquilateralTriangle : public GeometricFigure {
public:
EquilateralTriangle(double sideLength)
{
SideLength = sideLength;
}
char* Name() { return "Equilateral Triangle"; }
double Area() { return (sqrt(3) / 2 * pow(SideLength, 2)); }
};
In C++, the compiler reads your code from top-to-bottom, once. This is a holdover from when early C compilers only had a few kilobytes of memory to work with - C was designed so that a compiler would only need to look at a little bit of the code at a time.
Because of this, things must have been declared or defined as necessary, before you try to use them.
Move both classes somewhere before main. GeometricFigure must be before EquilateralTriangle, and EquilateralTriangle must be before main.
You would need to "declare" or tell the compiler, where to look for the EquilateralTriangle and GeometricFigure, "before" you use it first. you might want to take a look at the similar discussion at - C# declarations vs definitions

C++ Member Variable value changes based on whether or not it is printed out

I have a class ZoneDeVie containing a vector of vectors of Bacterie*. The Bacterie class contains an int value energie (set to 10 by default) and a toString() function which prints the value. In the ZoneDeVie constructor, I build the 2D table, populating each cell with a default instance of a Bacterie. Then, in my main method, I'm testing by printing the toString() of the last Bacterie in the table. For some reason, it returns a random, obnoxiously-large int (usually something like: 3753512); however, if I make a call to the Bacterie's toString() method in the constructor of ZoneDeVie, the main method will print out correctly.
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
class Bacterie {
public:
Bacterie() { this->energie = 10; }
string toString() {
stringstream ss;
ss << "Energie: " << this->energie;
return ss.str();
}
protected:
int energie;
};
class ZoneDeVie {
public:
ZoneDeVie(int width, int height) {
Bacterie* bac = new Bacterie();
// without this [following] line, the call to `toString`
// in the main method will return an obnoxiously-large value
//bac->toString();
for (int i=0; i<height; i++) {
vector<Bacterie*> bacvec = vector<Bacterie*>();
this->tableau.push_back(bacvec);
for (int j=0; j<width; j++) {
this->tableau[i].push_back(bac);
}
}
}
vector<vector<Bacterie*> > tableau;
};
int main(int argc, char *argv[]) {
int x,y;
x = 9; y = 39;
ZoneDeVie zdv = ZoneDeVie(10,40);
cout << "zdv(" << x << "," << y << ") = " << zdv.tableau[x][y]->toString();
return 0;
}
output (with a call to "toString()" in ZoneDeVie's constructor): zdv(9,39) = Energie: 10
output (w/o a call to "toString()" in ZoneDeVie's constructor): zdv(9,39) = Energie: 4990504
Why in the world do I need to call my toString() method before calling it in the main method in order for it to behave as expected?
The end condition in your for loops are swapped. You should first iterate through width and then through height:
class ZoneDeVie {
public:
ZoneDeVie(int width, int height) {
Bacterie* bac = new Bacterie();
for (int i=0; i<width; i++) {
vector<Bacterie*> bacvec = vector<Bacterie*>();
this->tableau.push_back(bacvec);
for (int j=0; j<height; j++) {
this->tableau[i].push_back(bac);
}
}
}
vector<vector<Bacterie*> > tableau;
};
This compiles and provides the correct output.
There are several issues with this code.
It's not clear what the default constructor of Bacterie does.
It's not clear what ZoneDeVie::tableau is and how the local vector bacvec is used.
It's not clear how the copy constructor and operator= for class ZoneDeVie are defined (both are used in main()).
It seems that all entries in your table are initialised with a pointer to the same Bacterie bac