Uninitialized object? What's wrong with this code. [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
For some reason, the code just crashes and gives me an Access Violation error. It keeps saying the object users is not initialized.
First-chance exception at 0x0F45E89A (msvcr110d.dll) in Random Coding
in C++.exe: 0xC0000005: Access violation writing location
0xABABABAB.Unhandled exception at 0x0F45E89A (msvcr110d.dll) in Random
Coding in C++.exe: 0xC0000005: Access violation writing location
0xABABABAB.
Thanks. Any ideas?
#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct User {
string name; //Both first and last name go here
int birthYear;
string major;
};
int main()
{
ifstream input("input.txt");
if(!input || !input.is_open())
return -1;
string buffer;
int count = -1;
int index = 0;
int size;
User* users;
while(getline(input, buffer, '\n'))
{
stringstream ss(buffer);
if(count == -1)
{
ss >> size;
users = new User[size];
count = 0;
}
else
{
if(count == 0)
{
users[index].name = buffer;
count++;
}
if(count == 1)
{
ss >> users[index].birthYear;
count++;
}
if(count == 2)
{
users[index].major = buffer;
count = 0;
index++;
}
}
}
for(int i = 0; i < 2; i++)
{
cout<<users[i].name << " " << users[i].birthYear << " " << users[i].major <<endl;
}
system ("PAUSE");
return 0;
}

for(int i = 0; i < 2; i++)
{
cout<<users[i].name << " " << users[i].birthYear << " " << users[i].major <<endl;
}
Looks incoorect. How are you so sure that users contain atleast two elements. If getline fails because of badfile or first line suggests only 1 record, you will get above exception.
You should change the loop to
// Initialize size with 0 before while(getline) loop
for(int i = 0; i < size; i++)
{
cout<<users[i].name << " " << users[i].birthYear << " " << users[i].major <<endl;
}
Also below lines of code look problematic
if(count == 0)
{
users[index].name = buffer;
count++;
}
if(count == 1)
{
ss >> users[index].birthYear;
count++;
}
if(count == 2)
{
users[index].major = buffer;
count = 0;
index++;
}
When count is 0, it would go into first if condition and get incremented. Then condition count == 1 would become true and you will visit next 2 conditions also. You should replace next 2 if conditions with else if or a switch with break statements to see the intended behavior.
Also it would be a good practice to free users after you are done with it.

What I think is that the first getline fails (the while does not enter, so nothing is created) and you automatically reach the for loop. Check in the for that you actually have users.

Related

Reading stack pop/push operations by text-file input

I have a text file with the following contents:
2
S 8
push 2 push 3 push 5 push 7 pop print push 6 print
S 4
pop print push 1 print
An assignment gives:
The first line of the input file means the number of test cases. For each test case, the first character means which container adapter (Stack or Queue) that you need to use Linked lists to implement. The correct output should be:
The values in the stack : 2 3 5
The values in the stack : 2 3 5 6
The values in the stack :
The values in the stack : 1
I've written some working functions for stack and queue struct, though I am working on the input of the stack function first.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void push(int);
int pop();
void printStack();
struct Stack {
int s[100];
int top;
Stack() { top = -1; }
};
Stack st;
void push(int n) {
if (st.top == 99) {
cout << "Stack full" << endl;
}
else {
st.s[++st.top] = n;
}
}
int pop() {
if (st.top == -1) {
cout << "Stack is empty" << endl;
}
else {
return st.s[st.top--];
}
}
void printStack() {
cout << "Elements";
for (int i = 0;i <= st.top;i++) {
cout << st.s[i] << ' ';
}
cout << endl;
}
void clearStack() {
st.top = -1;
}
The main part of the code is giving me trouble. I want to read every token of the text file while keeping the line structure; e.g. being able to parse by order of line. However, I do not know the length of each line, only the number of lines. How may I read the file correctly and finish this assignment?
int main() {
std::ifstream file("input1.txt");
std::string item_name;
int numTestCases;
vector<string> file_content{};
while (std::getline(file, item_name))
{
//cout << item_name << "\n";
char str[252];
strcpy(str, item_name.c_str());
char* pch;
//cout << "str0:" << str[0] << "\n";
file_content.push_back(str);
}
cout << "printing file content:" << endl;
for (int i = 0;i < file_content.size(); i++) {
cout << file_content[i] << endl;
}
}
Okay, you basically have two distinct problems.
Read your input file so you know what actions to perform.
Implement both Stack and Queue.
So start by breaking them up. I looked at your stack code. Your problem says to use linked lists, which isn't what you're doing. Maybe that's just because you haven't gotten that far yet.
Code like this would give you the number of test cases.
std::string numCasesStr;
if (!getline(file, numCasesStr)) {
cout << "early end of file detected\n";
return;
}
int numCases = std::stoi(numCasesStr);
At this point, you can now do this:
for (int testCase = 0; testCase < numCases; ++testCase) {
std::string typeAndCountStr;
if (!getline(file, typeAndCountStr)) {
cout << "early end of file detected\n";
return;
}
char typeC = typeAndCountStr.at(0);
if (typeC == 'S') {
...
}
else if (typeC == 'Q') {
...
}
}
The harder part is parsing the next line. You're going to get input in a similar fashion, but then you have to break it into pieces. This is called tokenizing. Basically you split it at each space. What's useful is the find method on a string.
do {
size_t lastPos = 0;
size_t pos = str.find(' ', lastPos);
string thisArg;
if (pos != string::npos) {
thisArg = str.substr(lastPos, pos);
lastPos = pos + 1;
}
else {
thisArg = str.substr(lastPos);
}
// At this point, thisArg contains one argument. You still have more
// to do, but this is one way to split your string into pieces.
} while (lastPos != string::npos);
What I do with that is stuff the individual pieces into a std::vector<std::string> and now it's a lot easier to deal with. You can traverse the vector, looking at each string, and depending upon what it is, you know if you have to grab the next item in the list (like push 8 -- you get push and then you get the 8) or just use the current item.
Overall -- break the problem down into smaller pieces. For main:
Get the number of test cases
Loop from 0..testCaseCnt
Get the type of tests (stack or queue)
Get the next input
Split it into tokens broken at each space
Traverse the tokens and Do The Right Thing (tm).
Code for main to read inputs:
int main() {
int numTestCases;
vector<string> file_content{};
fstream ifs;
ifs.open("input2.txt");
if (!ifs.is_open()) {
cout << "Failed to open file.\n";
}
else {
ifs >> numTestCases;
char type;
int numberOps;
//ifs >> type;
cout << numTestCases;
for (int j = 0;j < numTestCases;j++) {
ifs >> type;
ifs >> numberOps;
if (type == 'S') {
Stack st;
clearStack();
for (int i = 0;i < numberOps;i++) {
string operation;
ifs >> operation;
if (operation == "push") {
int pushed;
ifs >> pushed;
push(pushed);
}
if (operation == "pop") {
pop();
}
if (operation == "print") {
printStack();
}
}
}
}
ifs.close();
}
}

can someone please help solving this issue [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 12 months ago.
Improve this question
i appeared for a campus placement exam few days ago. then while solving it. I found it quite difficult to solve. And atlast i unable to solve it.
the question is as follows:
suppose we input a string of n length. then we have to give second input.that is number of charecters after which space needs to put.
example input:
joebiden
3
expected output
joe bid en
i code something like this.
#include <iostream>
using namespace std;
int main()
{
string str;
int space, con1 = 0, con2 = 0, con3 = 0, i = 0;
cin >> str;
cin >> space;
con1 = str.size();
for (con2 = 0; con2 < con1; con2++) {
for (con3 = 0; con3 < space; con3++) {
cout << str[con2];
if (con3 < (space - 1)) {
con2++;
}
}
cout << " ";
}
return 0;
}
You can use modulo operator to find on which index you should put space.
#include <iostream>
using namespace std;
int main() {
string str;
cin >> str;
int space;
cin >> space;
int n = str.length();
for (int i = 0; i < n; ++i) {
if (i % space == 0) cout << " ";
cout << str[i];
}
return 0;
}
This would be a working and also a shorter approach for your problem:
#include <iostream>
#include <string>
int main()
{
std::string input; std::cin >> input; // Ask the user for input
int segment_len; std::cin >> segment_len; // Ask the user for segment_len
if (segment_len > 0)
{
for (int i = segment_len; i < input.size(); i += segment_len)
{
input.insert(i++, 1, ' ');
}
}
std::cout << input;
return 0;
}
This application firstly takes in a string, then the segment length, and then adds a space after every segment_len characters.

Outfile causes crashes with a memory violation [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am writing a program to convert numbers from decimal to binary. I already have the algorithm correct for it and the program works fine while using cout. However, as soon as I use outfile in my loop the program crashes with error code (0xC0000005).
Here is my source code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
using namespace std;
int main()
{
int num, remainder_count;
ifstream infile; //define new input file stream
ofstream outfile; //define new output file stream
infile.open("C:\\Users\\Arctic-Gaming\\CLionProjects\\working\\Source\\Binary Conversion (Loop w File)\\Binary Input.txt"); //connect the stream to an actual file
if (!infile)
{
cout << "Cannot open input file! Program aborted" << endl;
return 1;
}
outfile.open("C:\\Users\\Arctic-Gaming\\CLionProjects\\working\\Source\\Binary Conversion (Loop w File)\\Decimal Output.txt"); //connect the stream to an actual file
do
{
int remainder [15] = {0};
remainder_count = 15;
infile >> num;
outfile << "\n" << num << endl;
if (num > 0 && num <= 65535)
{
while (num > 0)
{
remainder[remainder_count] = num % 2;
num /= 2;
remainder_count--;
}
remainder_count = 0;
while (remainder_count < 16)
{
if (remainder_count % 4 == 0)
{
outfile << " ";
}
outfile << remainder[remainder_count];
remainder_count++;
}
}
else if (num == 0)
outfile << "0000 0000 0000 0000" << endl;
else
cout << "Error! Invalid Input." << endl;
}
while (!infile.eof());
}
Your program has undefined behavior by accessing an element out-of-bounds. Since the behavior is undefined, the issue really has nothing to do with using std::cout as opposed to using file streams.
int remainder [15] = {0};
//...
remainder_count = 15;
//...
remainder[remainder_count] = num % 2; // out-of-bounds access (remainder[15] is out-of-bounds)
Once that line above is executed, all bets are off as to how your program will behave. The valid indices of an array range from 0 to n-1, where n is the number of elements in the array. So the valid indices are 0, 1, 2, up to 14 for the remainder array.
If you had switched to using std::array instead of regular C++ arrays, instead of undefined behavior, you would get an std::out_of_range exception thrown as soon as you access that element using at().
std::array<int, 15> remainder= {{0}};
remainder_count = 15;
//...
if (num > 0 && num <= 65535)
{
while (num > 0)
{
remainder.at(remainder_count) = num % 2; //... exception thrown
Live Example
So as you see, your program never "ran fine" as you claimed, and you will have to fix your program so that you are not going out-of-bounds of your array.

looping through a character array c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
#include <iostream>
#include <string>
using namespace std;
bool custNum(char [], int);
int main()
{
const int size = 8;
char custmor[size];
cout << "Enter a customer number in the form ";
cout << "LLLNNNN\n";
cout << "(LLL = letters and NNNN = numbers): ";
cin.getline(custmor, size);
if(custNum(custmor, size))
cout<<"That's a valid id number"<<endl;
else
cout<<"That's not a valid id number"<<endl;
return 0;
}
bool custNum(char custNum[], int size)
{
int count;
for(count = 0; count<3; count++)
{
if(!isalpha(custNum[count]))
return false;
}
for(count = 3; count <size - 1; count++) //3<7 , 4
{
if(!isdigit(custNum[count]))
return false;
}
return true;
}
so I want to loop through a character array of 3 letters and 4 numbers like ABC1234, but I didn't get the condition of the second for loop (size - 1). How does it work every time it tests the condition?
Never use count as a loop variable. A good name for a loop variable is i.
Never declare variables away from their initialization. The above should be for( int i = 0; ... in both cases.
i < size - 1 is probably wrong. What you probably want is i < size.
Anyhow, it would help if you showed how size is declared, how it is initialized, etc. It would also help if you showed the exact text you are trying to parse. It would also help if you explained exactly what you expected to happen, and exactly what happened instead. I might amend my answer when you do that.
you read only amount of characters that size variable specify,
since then , Why custNum function would not return true for anything longer than size variable ? , Because it's not checking anything more than what size variable specify.
Below is the code you need
#include <iostream>
#include <string>
using namespace std;
bool custNum(string,unsigned int);
int main()
{
const unsigned int size = 8;
//char custmor[size];
string mystring;
cout << "Enter a customer number in the form ";
cout << "LLLNNNN\n";
cout << "(LLL = letters and NNNN = numbers): ";
cin >> mystring;
cout << mystring <<endl << " " << mystring.length() << endl;
// cin.getline(custmor, size);
if(custNum(mystring , size))
cout<<"That's a valid id number"<<endl;
else
cout<<"That's not a valid id number"<<endl;
return 0;
}
bool custNum(string s, unsigned int size)
{
unsigned int count;
if (s.length() != (size + 1))
return false;
for(count = 0; count<3; count++)
{
if(!isalpha(s[count]))
return false;
}
for(count = 3; count <size - 1; count++) //3<7 , 4
{
cout << s[count] <<endl;
if(!isdigit(s[count]))
return false;
}
return true;
}

C++ Novice regarding Vectors and for/while loops

I’m trying to make something that will take lines of input from the user, separate them into strings in a vector, then print them one at a time (8 per line).
so far this is what I’ve got:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main(void)
{
using namespace std;
vector<string> svec1;
string temp;
while(getline(cin, temp)) //stores lines of text in temp
{
if(temp.empty()) //checks if temp is empty, exits loop if so.
break;
stringstream ss(temp);
string word;
while(ss >> word) //takes each word and stores it in a slot on the vector svec1
{
svec1.push_back(word);
}
}
}
I’m stuck on getting it to print them 8 at a time, the solutions I’ve tried keep getting subscript out of range errors.
Something like this:
for(int i = 0; i < svec1.size(); i++)
{
cout << svec1[i];
if ((i+1) % 8 == 0)
cout << endl;
else
cout << " ";
}
?
EDIT:
the solution above outputs extra space/newline at the end. It can be avoided by something like this:
for(int i = 0; i < svec1.size(); i++)
{
if (i == 0)
/*do nothing or output something at the beginning*/;
else if (i % 8 == 0)
cout << endl; /*separator between lines*/
else
cout << " "; /*separator between words in line*/
cout << svec1[i];
}
Walk over your vector with an index:
for (unsigned int idx = 0; idx < svec1.size(); ++idx) {
std::cout << svec[idx] << sep(idx); // sep(idx) is conceptual; described below
}
What is this sep(idx)? It is the separator to print after the idxth word. This is
A newline after having printed eight words on a line. idx will be 7, 15, 23, etc: One shy of an integer multiple of 8. In code, (idx+1)%8 == 0.
A newline for the last item in the vector; you probably want the last item to be followed with a newline. In code idx+1 == svec.size().
A space otherwise.
An easy way to do this is with the ternary operator:
for (unsigned int idx = 0; idx < svec1.size(); ++idx) {
const char * sep = (((idx+1)%8 == 0) || (idx+1 == svec.size())) ? "\n" : " ";
std::cout << svec[idx] << sep;
}
If you don't like that,
for (unsigned int idx = 0; idx < svec1.size(); ++idx) {
const char * sep;
if (((idx+1)%8 == 0) || (idx+1 == svec.size())) {
sep = "\n";
}
else {
sep = " ";
}
std::cout << svec[idx] << sep;
}
Normally you iterate over a vector using a for loop clause. So if you want to print all elements of your vector<string> you have to make something like this:
for(vector<string>::iterator it = myvec.begin(); it != myvec.end(); ++it) {
cout << *it;
}
EDIT: as Vlad has posted correctly, you can also use array indices, which are less efficient in lists, but equally efficient with vectors.