c++ program crash when inputing text file into array - c++

i am new at c++, i am trying to make a program that can input a matriks from ftitikberat.txt with this format:
id[...] -> matriks id
row[id[...]] -> number of matriks rows
coloumns[id[...]] -> number of matriks coloumns
matriks[id[...]] [row[id[...]]] [col[id[...]]] -> matriks
name[id[...]] -> matriks name
the program can be compiled, but when i try to input ftitikberat.txt its always crash
here's the code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int row[1000];
int col[1000];
int matriks[1000][4][4];
int id[1000];
int i,j,k;
string name[1000];
ifstream ifile("ftitikberat.txt");
for(i=1; i<=1000; i++)
{
ifile>>id[i]>>name[i]>>row[i]>>col[i];
for(j=1; j<=row[id[i]]; j++)
{
for(k=1; k<=col[id[i]]; k++)
{
ifile>>matriks[id[i]][j][k];
}
}
}
ifile.close();
and for the text:
1 null 1 1 0
2 null 1 1 0
3 null 1 1 0
4 null 1 1 0
.
. //until
.
998 null 1 1 0
999 null 1 1 0
1000 null 1 1 0
i have tried to change the text to:
...
998 null 1 1 0 1
...
and when i try to compile and run it, the program work just fine, except i cant use id 999 and 1000 because it just messed up, same when i tried to change the text at id 997 (997 null 1 1 0 1) and program didn't crash but i cant use id 998,999,1000
i have also tried to change maximal array one by one, and the program didn't crash when i change maximal array of (id and name) from 1000 to 1001, but i dont know why its work
can somebody please explain me why the program (before i changing text/maximal array) didn't work? i staring at this simple program like hours, but still don't know where the problem is :')

Array indexes go from 0 to size-1, not from 1 to size. So you're accessing outside the arrays when you do:
for(i=1; i<=1000; i++)
it should be:
for (i = 0; i < 1000; i++)
Your other loops should also start from 0 and use < instead of <=.

Related

printing 1D array in 6 columns

So I encountered this problem of not knowing how to display my random numbers from an array. The display should have 6 columns and I don’t know how about the rows. It is up to the user to enter amount of numbers in the array. Then, rand() will generate the numbers and display them in 6 columns like that (IF USER ENTERED 26 NUMBERS)
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1
I know how to generate the numbers and all that, my problem is only in displaying 1d array in that format. (the output has to compatible with other numbers entered as well not only 26) Any help or pointing in the right direction would be much appreciated.
Thanks,
uszy 123345.
Since you worry about just the output, you can insert a newline character every 6 numbers printed and just stop when you get at the end of the array.
Very often in c++ programming you can make use of extra variables to accomplish something every X number of iterations in a loop. In your case it looks like you want to insert a newline after every 6 numbers. Here is an example of how you would do that in code:
//I am assuming an array called arr with 26 elements already exists
for(int x = 1, i = 0; i < 26; ++i)
{
std::cout << arr[i] << ' ';
x++;
if(x == 6)
{
std::cout << std::endl;
x = 0;
}
}

Unexpected result 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 7 years ago.
Improve this question
I am creating a Minesweeper game. However, while testing the generating function, It malfunctions almost always (if not always), and I do not understand why.
Here is my code:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
struct board {
int width=9, mines=10;
char board[9][9];
/* char board[][]
* -1 = Mine
* 0 = No mines near
* 0+ = x amount of mines are near
*/
};
struct point {
int x,y;
};
board newBoard(){
board board1;
point randPoint;
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++) board1.board[i][j]=0; // Initialize array
}
for(int i=0;i<board1.mines;i++){
randPoint.x=rand()%board1.width, randPoint.y=rand()%board1.width; // Where will the mine go?
if(board1.board[randPoint.x][randPoint.y]!=-1){ // If not already a mine
board1.board[randPoint.x][randPoint.y]=-1; //make a mine
} else i--; //else don't count this
}
for(int i=0;i<board1.width;i++){
for(int j=0;j<board1.width;j++){
if(board1.board[i][j]==-1) { // If mine exists
// The if checks preceding the ++'s are to prevent out of bounds erors
if (j-1>=0) board1.board[i][j-1]++;
if (j+1<board1.width) board1.board[i][j+1]++;
if (i-1>=0) board1.board[i-1][j]++;
if (i+1<board1.width) board1.board[i+1][j]++;
if ((i-1>=0) && (j-1>=0)) board1.board[i-1][j-1]++;
if ((i-1>=0) && (j+1<board1.width))board1.board[i-1][j+1]++;
if ((i+1<board1.width) && (j-1>=0))board1.board[i+1][j-1]++;
if ((i+1<board1.width) && (j+1<board1.width))board1.board[i+1][j+1]++;
}
}
}
return board1;
}
int main() {
board boardGame=newBoard();
printf("- ");
for(int i=0;i<boardGame.width;i++) printf("%i ",i+1);
printf("\n\n");
for(int i=0;i<boardGame.width;i++){
printf("%i. ",i+1);
for(int j=0;j<boardGame.width;j++) if (boardGame.board[i][j]==-1) {
printf(" X");
} else {
printf(" %i", boardGame.board[i][j]);
}
printf("\n");
}
return 0;
}
This produces:
- 1 2 3 4 5 6 7 8 9
1. 0 0 0 0 1 X 1 0 0
2. 1 1 0 0 2 2 2 1 1
3. X 2 1 1 1 X 1 1 X
4. 1 2 X 0 1 1 0 1 1
5. 0 1 1 1 0 0 0 0 0
6. 0 0 0 0 1 1 1 0 0
7. 0 0 1 1 2 X 1 0 0
8. 1 1 2 X 2 1 1 0 0
9. 1 X 2 1 1 0 0 0 0
As you most likely already know, in the game of minesweeper, there is mines (in this case will they will be marked as X), and all nearby grid points are the number of mines near it (if you are still unfamiliar with it this page may of use). As you can see, the numbers at 4,7 and 4,4 are incorrect.
I do not know why this is this way. Could someone aid my understanding in this, and tell my how to to fix this?
Also, I just noticed that this produces the same output every time it is run. Why?
Ioums is correct, you are not checking to see if a cell is a mine before incrementing it. However, with the way that your code is currently set up, this will mean adding a check that the cell does not equal -1 in every single if statement. You should consider creating a function to safely increment a cell if it is within bounds and not a mine, like so:
void safeIncrement(int x, int y, board& b)
{
if(x >= 0 && y >= 0 && x < b.width && y < b.width && b.board[x][y] != -1)
{
b.board[x][y]++;
}
}
This means that you can replace your if statements with:
safeIncrement(i-1,j,board1);
safeIncrement(i-1,j-1,board1);
safeIncrement(i-1,j+1,board1);
safeIncrement(i,j-1,board1);
safeIncrement(i,j+1,board1);
safeIncrement(i+1,j,board1);
safeIncrement(i+1,j-1,board1);
safeIncrement(i+1,j+1,board1);
Which is much more readable in my opinion. Additionally, since the function doesn't increment the cell if it is a mine, you could also replace the if statements with the following code!
for(int a=-1; a<=1; a++)
{
for(int b=-1; b<=1; b++)
{
safeIncrement(i+a,j+b, board1);
}
}
The problem happens when 2 mines are close together: when you're adding to the mine count, you don't check if that square has a mine.
Suppose you get a mine on (0, 0) and another on (0, 1). When you're adding to the mine count around (0, 0), you accidentally also add to the mine in (0, 1), changing it from -1 to 0. It also makes the second mine being processed disappear.
I suggest using another number to signal a mine, like -999, and check if the number is negative when looking for them. It's easier than adding another condition for all if clauses you already have.

int variable not resetting on c++?

So, my program is supposed to receive test inputs like:
3
1 0 1
0 1 1
1 0 1
5
1 1 1 0 0
1 1 0 1 1
1 0 1 0 1
0 1 0 1 0
0 1 1 1 1
3
1 0 0
0 1 0
0 0 1
2
1 1
1 1
0
where the single-valued lines (n) are the size of a NxN matrix located in the following n entries like shown above. If n = 0, the program stops. The output must be the biggest sum amongst the columns of the matrix. So I expect outputs like this:
3
4
1
2
After a lot of effort and wasted time, I managed to get the first output correctly, but I noticed the following ones sometimes summed up and suggested some variable was not being reset. Here's my code:
#include <iostream>
using namespace std;
int pop = 0;
int main() {
int n, i, j, k;
cin >> n;
while (n!=0) {
int alunos[n]={0};
pop = 0;
for (i=0;i<n;i++) {
int array[n]={0};
for (j=0;j<n;j++) {
cin >> array[j];
if (array[j]==1) alunos[j]++;
}
}
for (k=0;k<n;k++) {
if(alunos[k]>pop) pop = alunos[k];
}
cout << pop << endl;
cin >> n;
}
return 0;
}
Noticed that I'm outputting pop(the biggest sum) and resetting it to 0 everytime a new n is given. alunos[n] is an array with the sums of each column (also resetted on every while loop) and array[n] is just an auxiliary array for reading each line of input. My outputs with this are:
3
5
6
8
Thanks in advance!
You cannot use initializers with variable length arrays. Either switch to some sort of container:
std::vector<int> alunos(n);
or fill the array with zeros manually:
int alunos[n];
std::fill(alunos, alunos+n, 0);
Also, ignoring errors is unhealthy. Don't do it.

Copying data file into an array

I have a project for school. They gave me a data file that needs to be in an array of 10*10. This array needs to be an upper triangle, which means that all values of and below the diagonal have to be zero. This data file is the time that a project takes by every stage. It means that every [i][j] represents the time for stage from i to j.
Just to make it more complicated the problem ask you to find the longest time per column and add it to the longest time in the next column.
here is my code so far:
#include <iostream>
#include<iomanip>
#include <fstream>
#include <cmath>
using namespace std;
//Function prototype
int minCompletionTime (int Data[], int numTasks);
int main()
{
//Declaring and initializing variables
int num_Events(0), completion_Time(0);
int startSearch(0), endSearch(0);
const int SIZE(10);
char datch;
//Declaring an array to hold the duration of each composite activity
int rows(0),duration_Data [10];
//Declaring an input filestream and attaching it to the data file
ifstream dataFile;
dataFile.open("duration.dat");
//Reading the data file and inputting it to the array. Reads until eof
//marker is read
while (!dataFile.eof())
{
//Declaring an index variable for the array
//Reading data into elements of the array
dataFile >> duration_Data[rows];
//Incrementing the index variable
rows++;
}
//Taking input for the number of events in the project
cout << "Enter the number of events in the project >>> ";
cin >> num_Events;
//Calling the function to calculate the minimum completion time
completion_Time = minCompletionTime(duration_Data, num_Events);
//Outputting the minimum completion time
cout << "The minimum time to complete this project is " << completion_Time
<< "." << endl;
}
int minCompletionTime (int Data[], int numTasks)
{
int sum=0;
//As long as the index variable is less than the number of tasks to be
//completed, the time to complete the task stored in each cell will be
//added to a sum variable
for (int Idx=0; Idx < numTasks ; Idx++)
{
sum += Data[Idx];
}
return sum;
}
Any help will be appreciated
My data file only has 6 elements that holds this elements: 9 8 0 0 7 5
my data should look like this in order to start doing operations.
0 0 0 0 0 0 0 0 0 0
0 0 9 8 0 0 0 0 0 0
0 0 0 0 7 0 0 0 0 0
0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
It is a little confusing. I am sorry. The first and second column should have values of zero and first row the same way. after fifth row should be all zeros as well since it will be filled with more information from other data file.
There are a few ways of solving this problem. Here are 2 very naive ways:
1. Use a 10x10 array:
Read everything in from the data file (dataFile >> data[row][col]).
Have 2 nested loops:
The outer loop iterates over columns.
The inner loop iterates over the rows of that specific column.
Since you have to find the max and the values under the diagonal is zero, you can just be lazy and find the max of each column (you might have trouble if it's a lot larger than 10x10). However, if you want to only go through the rows that are necessary, I'll let you figure it out (it's very simple, don't over think).
2. Only use a 1x10 array:
Initialize the array with the minimal value (0 or -1 should work for you), let's call it the max_row.
Read item by item on each row, and compare it to the value that's stored in the max_row and replace appropriately.
When you're done, just sum up the elements in max_row.

Why does it cout in something that we doesn't cin in arrays?

When the following program is fead the following input (reading from cin):
1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1
The output is surprising:
1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1
#include<iostream>
using namespace std;
int main()
{
int arey[3][3];
int i,j;
for(j=0;j<=3;j++)
{
for(i=0;i<=3;i++)
{
cin>>arey[j][i];
}
}
arey[0][0]=1;
arey[3][3]=1;
i=0,j=0;
for(j=0;j<=3;j++)
{
for(i=0;i<=3;i++)
{
cout<<arey[j][i];
}
}
return 0;
}
Can someone explain what I should change to get the same output as the input?
Is the matrix 3x3 or 4x4?
you created 3x3 but the loops run for 4 elements and you also update [3][3]
Basically your indexes overflow and you overwrite a different cell in the matrix.
Update: cheecked your input, use: int arey[4][4];
Arrays use 0 based indices, so the valid range of indices for your
int arey[3][3];
are 0 <= i < 3 and 0 <= j < 3
So you need to change the condition in your for loops to be strictly < instead of <=
I really don't think I understand your question, but this is wrong:
int arey[3][3];
...
for(j=0;j<=3;j++) // <= invalid
...
array[3][3]=1; // out of bounds
arey is a 3*3 array. You can't access arey[3][?], that's out of bounds. The only valid indices are 0..2.
Once you've written past the bounds of your array, your program behavior becomes undefined.