Uninitialised local variable from class - c++

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[...]

Related

std::cout is not printing

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

Discerning between struct indexing and size initialization

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.

What is the problem I am having with using arrays with classes?

I have been working on a project for my computer science class and have encountered an issue with the code working. I am shown no error except when I try to compile and I get an error that reads:
Exception thrown: write access violation.
_Left was 0xCCCCCCCC.
The purpose of my project is to take a list of names from an external file, read them into an array, sort said array and then output the sorted list all while using a class for the code.
Here is a copy of my code and I would like to extend my gratitude to whoever can help me through my issue:
**Header File**
#include <iostream>
using namespace std;
class person
{
public:
person();
bool get(ifstream&);
void put(ofstream&);
private:
int capacity = 0;
string first_name[CAPACITY];
string last_name[CAPACITY];
int age[CAPACITY];
};```
**Header function definitions cpp file**
#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>
const int CAPACITY=20;
using namespace std;
#include "Person.h"
//Names constructor
//Postcondition both first name and last name initialized to zero
person::person()
{
first_name[CAPACITY] = "";
last_name[CAPACITY] = "";
age[CAPACITY]=0;
}
bool person::get(ifstream& in)
{
in >> first_name[CAPACITY] >> last_name[CAPACITY] >> age[CAPACITY];
return(in.good());
}
void person::put(ofstream &out)
{
out << first_name[CAPACITY] << last_name[CAPACITY] << age[CAPACITY];
}
**cpp file which holds main**
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
const int CAPACITY = 20;
using namespace std;
#include "Person.h"
void pop(string *xp, string *yp);
void sort(string name[CAPACITY], int count);
int main()
{
class person names[CAPACITY];
ifstream infile;
ofstream outfile;
string filename;
string name[CAPACITY];
int n = 0;
cout << "Enter the file name you wish to open" << endl;
cin >> filename;
infile.open(filename + ".txt");
outfile.open("Person_New.txt");
if (infile.fail())
{
cout << "The file requested did not open" << endl;
exit(1);
}
while (!infile.eof())
{
names[n].get(infile);
n++;
}
sort(name, CAPACITY);
for (int i = 0; i < CAPACITY; i++)
{
names[i].put(outfile);
}
cout << "The file has been created" << endl;
infile.close();
}
void pop(string *xp, string *yp)
{
string temp = *xp;
*xp = *yp;
*yp = temp;
}
void sort(string name[CAPACITY], int count)
{
int i, j;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (name[j] > name[j + 1])
{
pop(&name[j], &name[j + 1]);
}
}
}
}
Once again Thank you for any support
It sounds to me like the compiler is getting upset that you are trying to write (i.e. assign a value) at an address that you do not have permission to access. I believe your constructor for the class person might be at fault because of how this class stores its variables, as well as the class header:
Constructor for the class person:
`person::person(){
first_name[CAPACITY] = "";
last_name[CAPACITY] = "";
age[CAPACITY] = 0;
}`
Class header for the class person:
`class person{
public:
//stuff
private:
int capacity = 0;
std::string first_name[CAPACITY];
std::string last_name[CAPACITY];
int age[CAPACITY];
//more stuff
}`
C++ is very specific about its naming conventions, so it makes a distinction between capacity and CAPACITY. Because of this, the variable CAPACITY is not defined within the Person.h file.
Also, because CAPACITY is set to a fixed value in your Person.cpp file, whenever you use first_name[CAPACITY], last_name[CAPACITY], or age[CAPACITY] to assign new values, you are only updating the values at the index equal to CAPACITY unless you update the value of CAPACITY itself. In the code you provided, CAPACITY is equal to 20, so your program attempts to update exclusively index 20 with each method call. This will likely cause issues since the person class only attempts to make its arrays on the runtime stack, with a size of 0 each.
Separately, it seems like you want an array of people, but it appears that you are attempting to use a single person object to store the names and ages of multiple people by making these all arrays. Instead, I would recommend making first_name, last_name, and age not arrays, but rather single variables. Then, you can manipulate an array of type person using your CAPACITY variable. You got pretty close, but you can instead declare it as person myPersonArray[CAPACITY] (no need to mention "class" in front of it -- just be sure that you have #include "Person.h" in your main.cpp file). When you want to update a specific person, you can perform an operation like myPersonArray[updateThisIndexNum].update(newFirstName, newLastName, newAge) or some logical equivalent.
As a final note, I almost always highly recommend against using !infile.eof() to control your while loop when reading any file because eof() only indicates whether you have tried to read past the end of an input file. I would highly recommend checking out this post on Stack Overflow where people far more knowledgeable than I explain exactly why this is usually dangerous and how to avoid it.

Through what to call the method, if I already created constructor with initialization of array of structures?

I'm trying to call the method displayChoices, member of the class MachineManager through the object of the class. But I already have a constructor with initializing of the array of structures. How I understood when we create an object of the class compiler implicitly create a default constructor of the class.
Question: How to call method displayChoices?
#include "MachineManager.h"
using namespace std;
int main()
{
MachineManager mjp;
mjp.displayChoices();
return 0;
}
struct BrewInfo {
string* DrinkName;
double* Cost;
int* Number;
};
class MachineManager {
static const int Num_Drinks = 3; /// why it works only with static?!!!
BrewInfo* BrewArr[Num_Drinks];
public:
MachineManager()
{
*BrewArr[0]->Cost = 1.25;
*BrewArr[0]->Number = 20;
*BrewArr[1]->DrinkName = "pepsi";
*BrewArr[1]->Cost = 1.15;
*BrewArr[1]->Number = 17;
*BrewArr[2]->DrinkName = "Aloe";
*BrewArr[2]->Cost = 2.00;
*BrewArr[2]->Number = 15;
};
int displayChoices();
}
int MachineManager::displayChoices() // (which displays a menu of drink names and prices)
{
cout << 1;
int choice;
cout << "|1." << *BrewArr[0]->DrinkName << " |2." << *BrewArr[1]->DrinkName << " |3." << *BrewArr[2]->DrinkName << " |" << endl;
cin >> choice;
if (!choice || choice == 0) {
system("slc");
displayChoices();
}
else
return choice;
}
displayChoices has to print a menu in console.
You have a majo bug in your source code. You do not yet understand, how pointer work.
You are defining an array of pointer with BrewInfo* BrewArr[Num_Drinks];.
But these pointers are not initialized. They point to somewhere. Then you are dereferencing those pointers (pointing to somewhere) and assigning a value to somewhere in the memory.
This is a major bug.
The array dimensions for C-Sytle arrays must be a compile time constant.
You cannot write
int x=3;
unt array[x];
This is C99 code (called VLA, Variable length array), but not C++.
Solution for you problem:
Do never use C-Style arrays, like int array[5]. Use STL container like std::vector instead.
Do not use pointers.
This is your major problem. Define your array with BrewInfo BrewArr[Num_Drinks];. Please remove also the pointer from
struct BrewInfo {
string* DrinkName;
double* Cost;
int* Number;
};

C++ Dynamic Array: A value of type "void" cannot be used to initialize an entity of type "int"

I am working on a C++ project for school in which the program will read in a list of numbers from a text file, store them in a dynamic array, then print them out to another text file. To be honest I'm a little lost with the pointers in this, and I am getting the error "A value of type "void" cannot be used to initialize an entity of type "int"" in my main source file.
Main.cpp (this is where I'm getting the error):
#include "dynamic.h"
int main
{
readDynamicData("input.txt","output.txt");
}
dynamic.cpp (the skeleton for the program):
#include "dynamic.h"
void readDynamicData(string input, string output)
{
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
int *temp = da.theArray;
da.theArray = new int[da.size];
ifstream in(input);
ofstream out(output);
in >> da.number; //prime read
while (!in.fail())
{
if (da.count < da.size)
{
da.theArray[da.count] = da.number;
da.count++;
in >> da.number; //reprime
}
else grow; //if there are more numbers than the array size, grow the array
}
out << "Size: " << da.size << endl;
out << "Count: " << da.count << endl;
out << "Data:" << endl;
for (int i = 0; i < da.size; i++)
out << da.theArray[i];
in.close();
out.close();
delete[] temp;
}
void grow(DynamicArray &da) //this portion was given to us
{
int *temp = da.theArray;
da.theArray = new int[da.size * 2];
for (int i = 0; i<da.size; i++)
da.theArray[i] = temp[i];
delete[] temp;
da.size = da.size * 2;
}
and dynamic.h, the header file:
#include <iostream>
#include <string>
#include <fstream>
#ifndef _DynamicArray_
#define _DynamicArray_
using namespace std;
void readDynamicData(string input, string output);
struct DynamicArray
{
int *theArray;
int count;
int size;
int number;
};
void grow(DynamicArray &da);
#endif
you have to add parenthesis to main or any function:
int main(){/*your code here ...*/};
2- you are using an unitialized objct:
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
so int* theArray is a member data and is uninitialized so welcome to a segfault
all the members of da are not initialized so you have to do before using it.
3- also you add parenthesis to grow function:
else grow(/*some parameter here*/); // grow is a function
4- using namespace std; in a header file is a very bad practice.
tip use it inside source
5- why making inclusion of iostream and string.. before the inclusion guard??
correct it to:
#ifndef _DynamicArray_
#define _DynamicArray_
#include <iostream>
#include <string>
#include <fstream>
/*your code here*/
#endif
main is a function so it needs brackets:
int main(){
// your code
return 0; // because it should return intiger
}
And. Your grow is also a function, so if you want to call it you write grow() and it needs DynamicArray as a parameter.
It is impossible to write working programs on C/C++ any programming language not knowing a basic syntax.