C++ Program stopped working after reading large text in freopen - c++

i was generating output from txt, and the input from txt too, but, the the txt file is 79MB. I don't know why it's stopped working, and also, i use loop for the input, the line in the input text is 9.000.000 lines, so i need to loop 3000^2 , but i don't know what's wrong, it's just crashing after i compile it.
Here's the code
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(0);
freopen("hex.txt","r",stdin);
freopen("css.txt","w",stdout);
cout << ".container{\nwidth: 3000px;\nheight: 3000px;\n}\n";
cout << ".px{\nfloat: left;\nwidth: 1px;\nheight: 1px;\n}\n";
string hex[3000][3000];
for (int i=0; i<3000; i++)
{
for (int j=0; j<3000; j++)
{
cin >> hex[i][j];
}
}
for (int i=0; i<3000; i++)
{
for (int j=0; j<3000; j++)
{
cout << ".b" << i+1 << "k" << j+1 << "{\nbackground: "<< hex[i][j] << ";\n}" << endl << endl;
}
Note: hex.txt size is 79MB, and when it stopped working, the "css.txt" (output file) is not exist, i'm sure it's crash when the program trying to reading freopen("hex.txt","r",stdin);
i use Codeblocks 16.01 also if i remove the line 5 in the code, it's still crash, and i just debug it in my codeblocks it said segmentation fault, how do i fix this? thanks!
EDIT: Problem solved by cout immediately after cin, and that's work! i didn't try using vector yet, but now i know that using string hex[3000][3000] didn't work because the space is too small.
Sorry my bad english.

string hex[3000][3000];
Stack space is too small to allocate large arrays, you can use vector<vector<string>> to avoid this situation.
Such as
vector<vector<string> > hex(3000, vector<string>(3000));

Related

Simple Cipher with std:out_of_range issue (C++)

I'm totally new to programming and heard that C++ or the Assembly Language is a good startning point for someone that want to understand what happens under the hood. I want to follow this follow through even though some of you might have other suggestions. I've been an active student for a week now and for my second challange my teacher asked us to write a cypher. Nothing fancy, but something that scrambled and unscrambled the string written by the user. So far I've tried to scramble them for starters since I deduce that if I'll solve that problem, the unscramling will be achieved through a similar process. I know there's plenty of snippets of code out there already, but I'm really intressted and want to learn through the trial and error method, based on my own assumptions.
I would appriciate it greatly if someone could point out why I get the message: "Terminate called after throwing an instance of 'std::out_of_range'
#include <iostream>
#include <string>
using namespace std;
string latSorted {"abcdefghijklmnopqrstuvwxyz ,."};
string latUnstorted {"-_qazwsxedcrfvtgbyhnujmikolp"};
int main() {
cout << "\n -----------------------------------------------" << endl;
cout << " Enter some text: ";
string usrText;
string* p_usrText; // Pointer Initialization
cin >> usrText; // User enter text
p_usrText = &usrText; // Memory allocation gets assigned to the pointer variable
cout << " You've entered " << *p_usrText << endl << endl;
for (size_t i=0; i < latSorted.length(); i++)
{
char searchChar = latSorted.at(i);
char cryptChar = latUnstorted.at(i);
for(size_t j=0; j < usrText.length(); j++)
{
if(usrText.at(j) == searchChar)
{
*p_usrText = usrText.replace(usrText.begin(), usrText.end(), searchChar, cryptChar); // Memory allocation is still within range due to the pointer. Should not say "out of range".
}
}
}
cout << ' ' << usrText << endl;
cout << endl;
return 0;
}
Thx//Alle
It appears that latSorted and latUnstorted are different lengths.
char cryptChar = latUnstorted.at(i);
Would result in the exception for the last value of i.

Code crashes. Trying to remove characters from char array C

I am basically trying to store everything after a certain index in the array.
For example, I want to store a name which is declared as char name[10]. If the user inputs in say 15 characters, it will ignore the first five characters and store the rest in the char array, however, my program crashes.
This is my code
char name[10];
cout<< "Starting position:" << endl;
cin >> startPos;
for(int i= startPos; i< startPos+10; i++)
{
cout << i << endl; // THIS WORKS
cout << i-startPos << endl; // THIS WORKS
name[i-startPos] = name[i]; // THIS CRASHES
}
For example, if my name was McStevesonse, I want the program to just store everything from the 3rd position, so the end result is Stevesonse
I would really appreciate it if someone could help me fix this crash.
Thanks
Suppose i is equal to 3. In the last iteration of the loop, i is now equal to 12, so substituting 12 in for i, your last line reads
name[12-startPos] = name[12];
name[12] is out of bounds of the array. Based on what you have shown so far, there is nothing but garbage stored in name anyway before you start doing this assignment, so all you're doing is reorganizing garbage in the array.
Please in future: post full compilable example.
A simple answer is that your array maybe is out of bound, since you don't provide full example its hard to know exactly.
Here is a working example:
#include <iostream>
using namespace std;
int main() {
int new_length, startPos;
int length = 15;
char name[15]= "McStevesonse";
cout<< "Starting position:" << endl;
cin >> startPos;
if(new_length <1){ // you need to check for negative or zero value!!!
cout << "max starting point is " <<length-1 << endl;
return -1;
}
new_length=length-startPos;
char newname[new_length];
for(int i= 0; i<new_length; i++){
newname[i] = name[i+startPos]; // THIS CRASHES
}
cout << "old name: " << name << " new name: " << newname << endl;
return 0 ;
}
To put it simply, change this:
for(int i= startPos; i< startPos+10; i++)
To this:
for(int i= startPos; i<10; i++)
You should be fine with that.
Explanation:
At some point, when you use the your old loop, this name[i-startPos] = name[i] would eventually reach an array index out of bounds and causes the crash.
Don't forget to clean up/hide the garbage:
Doing so, would cause the output to produce some kind of garbage outputs. If you got a character array of 'ABCDEFGHIJ', and have chosen 3 as the starting position, the array would be arranged to 'DEFGHIJHIJ'. In your output, you should atleast hide the excess characters, or remove by placing \0's

C++ text file into multi-dimensional array problems

As part of a school project, I would like to get an inventory *.txt file into an array in C++ and eventually back to a *.txt file at a later part in the program.
The text file will start out with 10 rows that will represent grocery story items and will include three columns that represent the name, price, and quantity of the items. I have been able to read from the file, even add numbers in front of each row that is displayed. Now, I would like to get the text file into a string array so that the "employee" user can make changes to items one at a time and then I can dump that array back into a *.txt file.
The code below is what I have been trying so far. I can get the count of rows in the file, but can't seem to get the columns counted or the data in the rows displayed. When I run the program, I get what appear to be 10 empty lines after it displays the rows (10) and Cols(0).
The columns in the *.txt file are normally separated by a space. I tried a tab, and tried: while(getline(invFile, lines, '\t'); which just caused the console to display what I am guessing was a memory address and then crashed.
Unfortunately, we have not gotten very far into debugging programs, and from the look of the syllabus, I don't think that will be covered very thoroughly, so I don't know how to troubleshoot any further. I have spent the last couple of hours Google-ing, and have gotten to the point that I actually need to ask for help.
The project involves a lot more than this component, but I really am stuck on this part. I am not asking for someone to do this for me, but if anyone has any idea what I am doing wrong and can point me in the best direction to get a text file into a multi-dimensional array, I would really appreciate it.
Thank you.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <array>
int row = 0;
int col = 0;
using namespace std;
int main()
{
string lines;
int x;
string textArray[2][2];
ifstream invFile;
invFile.open("inventory.txt");
if(invFile.fail()){
cerr << "The file cannot be opened!";
exit(1);
}
cout << "\n" << endl;
while(invFile.good()) {
while(getline(invFile, lines)) {
istringstream streamA(lines);
col = 0;
while(streamA >> x) {
cout << x;
textArray[row][col] = x;
col++;
}
row++;
}
}
invFile.close();
cout << "Rows: " << row << endl;
cout << "Cols: " << col << endl;
cout << "\n" << endl;
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
cout << "Line: " << i << textArray[i][j] << ".";
}
cout << "\n";
}
return(0);
}
=============================
inventory.txt:
Apples 1.25 20
Oranges 1.75 20
Kiwi 2.50 15
Pineapples 5.50 20
Tomatoes 1.50 20
Onions 2.00 20
Corn 1.80 20
Carrots 2.30 20
Milk 4.50 20
Cheese 2.25 20
I would suggest that you create a struct or class to hold the data. From each line of text, extract the fields appropriately and them to your struct. Then, keep a list of those structs using std::vector.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sstream>
#include <array>
#include <vector>
#include <cstdlib>
using namespace std;
struct Row
{
vector<string> columns;
};
int main()
{
string line;
vector<Row> rows;
ifstream invFile;
invFile.open("inventory.txt");
if(invFile.fail()){
cerr << "The file cannot be opened!";
exit(1);
}
cout << "\n" << endl;
while(invFile.good()) {
while(getline(invFile, line))
{
Row row;
istringstream streamA(line);
string col;
while ( streamA >> col )
{
row.columns.push_back(col);
}
rows.push_back(row);
}
}
invFile.close();
cout << "Rows: " << rows.size() << endl;
cout << "Cols: " << rows[0].columns.size() << endl;
cout << "\n" << endl;
for(int i=0; i<rows.size(); i++){
for(int j=0; j<rows[i].columns.size(); j++){
cout << "Line: " << i << " " << rows[i].columns[j] << "\n";
}
cout << "\n";
}
return(0);
}
I'd like to suggest you add some print lines in the important step -- which I think also is a fast&good "debug" method. So that you can find where you wrong easily.
For example in your code, seems textArray wasn't assigned, so add some print nearby:
while(getline(invFile, lines)) {
cout <<"lines: " << lines << endl; //test enter here
istringstream streamA(lines);
col = 0;
while(streamA >> x) {
cout << "x is" << x; //test if enter here
textArray[row][col] = x;
col++;
}
row++;
}
Through the output, the lines is ok but cout << "x is" << x; wasn't printed, which means the while(streamA >>x) condition is false, why?
Go to find the library function called, std::istringstream x is int type but col 1 value is Apples, operator << will return NULL, it's unreasonable assing Apples to an int, till now, found point 1. If have to use int or float to store the numbers, use some convert API like atoi, atof.
After change x from int to string, got segmentation falut, it's obviously that textArray[2][2] is not enough to store all the information. "Out of range" is the reason of segmentation fault, so make a large array to test continue until passed.
There's a couple ways you could do this. The easiest would be to just put something like 3,10 at the top of the file, and then you know three columns and 10 rows. Since your writing this after modification, you would just need to make sure that those numbers get written correctly.
If you want to learn some more advanced methods, then your life will be easier AFTER you learn a bunch more.
If you used a vector, using something like vector< vector<string> > you could just read to a stringstream and then split the line read and put it into the vector
fstream file(...);
string tempString;
vector< vector<string> > list;
// Get a full line
while(getline(file, tempString, '\n'){
// Create a StringStream and store tempString in it for further manipulation
stringstream ss;
ss << tempString;
vector<string> tempVec;
// Get each column from this row
while(getline(ss, tempString, '\t'){
// Put each column into a vector
tempVec.push_back(tempString);
}
// Put the entire vector into our list vector
list.push_back(tempVec);
}
The benefit of this second method is twofold. First, it's very easy. I'm guessing you don't know how it works, but some easy Google searches on keywords you don't know, and you'll find out fast enough. The second is it allows (theoretically) unlimited rows, and unconstrained columns. By that, I mean one row could have 20 columns, one could have 2, and there would be no wasted space.
Note that you should NOT use the skeleton code I showed before researching it. If you don't have at least a general idea of what is happening here, then you'll just cause problems for yourself later on. I'm not going to explain everything here, because other people have done that already. Also, since you're learning this in school, you'll get to these things eventually, so you'll just be getting ahead. The one main constraint would be if your project requires arrays, in which case, my first solution would be the best option.

Subscripted value is not an array, pointer or vector, C++

So, I'm getting the above error (in the title) but for some reason it's only throwing this error on the second loop. Notice the first and second loop I have using the customer variable works absolutely fine, no errors thrown or anything. But on that last loop, the output[customer][charge] array, there is a red line under output[customer] that says "Subscripted value is not an array, pointer or vector". I am using xcode, Mavericks OSX. All of my arrays are defined elsewhere, and have worked perfectly the whole length of the program until now. There are some other operations going on in the program, but they have nothing to do with this loop, so I just posted the code that was giving the error. Again I'll say, the charges[customer][month][charge] loop works fine, but the output[customer][output] is not working.
P.S. You probably will think the logic behind keeping all this data in numerically indexed arrays is dumb, but it is for a school project. So don't lecture me about how this program is logically inconsistent or whatever. Thanks!
string headings[3][7];
string chargeLabels[3] = {"Electricity :","Water: ","Gas: "};
string outputLabels[5] = {"Subtotal: ","Discount: ","Subtotal: ","Tax: ","Total: "};
double charges[3][3][3];
double output[3][5];
for(int customer=0; customer<3; customer++)
{
for(int heading=0; heading<5; heading++)
{
cout << headings[customer][heading];
}
for(int month=0; month<3; month++)
{
cout << chargeLabels[month];
for(int charge=0; charge<3; charge++)
{
cout << charges[customer][month][charge] << ", ";
}
cout << endl;
}
for(int output=0; output<5; output++)
{
cout << outputLabels[output];
//error is below this comment
cout << output[customer][output] << endl;
}
}
Inside the for statement:
for(int output=0; output<5; output++)
{
You declared another variable int output which shadows the double output[3][5] with the same name outside the for statement.
Here's your problem:
double output[3][5];
for(int output=0; output<5; output++)
You're reusing output as a variable name twice.
So when you try to access it here:
cout << output[customer][output] << endl;
You're accessing the local output, which is just an int.

Using ASCII characters in C++ program

I've been trying to print out _ <------ this character in a 2D array... But when I
tried compiling the code, it returned some garbage numbers. I think I'm doing something wrong... can anyone please help me out to solve this problem ?
void main (){
int A[9][9];
for (int i=0; i<9; i++){
for (int j=0; j<i; j++){
A[i][j]= '_';//I am doing this part wrong.
}
}
for (int r=0; r<9; r++) {
for (int c=0; c<9; c++)
cout << setw(3) << A[r][c];
cout << endl;
}
system("pause");
}
A is an int array. So cout would try to print an integer. Try cout << char(A[r][c]);
The std::cout::operator<< operator is overloaded for several data types in order to facilitate (automagically-)formatted output. If you feed it an int, then it will print a number. If you give it a char, it will try to print it as a character. So either declare your array as an array of char, or cast the array member when printing:
cout << static_cast<char>(array[i][j]) << endl;
1. Assign the ASCII value to integer array rather than '_'. It will work even without change; but i feel it looks cleaner.
A[i][j]= 95; // try this instead of '_'
While printing, cout can print any data type without casting, but since we are looking for character to be printed, try explicit conversion.
cout << setw(3) << char(A[r][c]);
Not sure about the compiler you are using, but its a better practice to initialize the array to avoid garbage value tampering with your output