How can I fix error when adding elements to my array - c++

I am trying to add elements to my file using a method I have already used and was proven to be successful, however now when I do it I get the numbers I want as well as a bunch of other numbers that aren't in my file and don't make any sense
const int MAX_SIZE = 21;
int readSquare(int square[MAX_SIZE][MAX_SIZE], string inputFileName){ //reads file into an array
int value;
ifstream inFile;
inFile.open(inputFileName);
if (inFile) //if the input file to be read open successfully then goes on
{
int temp;
inFile >> temp;
if (temp>21) {
temp=21;
}
for (int i = 0; i < MAX_SIZE; i++)
{
for(int j = 0; j < MAX_SIZE; j++)
{
inFile >> square[i][j];
}
}
} else {
inFile.close();
return 0; //returns 0 if couldnt open file
}
inFile.close();
cout << "Magic square" << endl;
for(int i=0;i<MAX_SIZE;i++)
{
for(int j=0;j<MAX_SIZE;j++)
{
cout << square[i][j] << " ";
}
cout<<endl;
}
return 1;
}
This is the file I am using on my code
3
4 9 2
3 5 7
8 1 6
And this is the result I get(goes on for a while but I only took the top portion)
4 9 2 3 5 7 8 1 6 16840768 6619136 6643024 23198772 0 1942212500 127 917504 6643024 786434 6643032 0
65536 30 0 31 0 13930549 30 593 6619744 6619744 -2 127 46 6420808 1997546816 -1759127226 -2 6420704 1997359545 4096 4104
0 6420680 6634144 6619136 6421232 4104 6619744 0 3 0 4096 6420732 1997535944 6420804 655612 655360 2 9 0 2 6420976
0 1997378284 6420976 663276 1952 229640288 663200 655360 0 1997377793 6421060 661336 9 16777596 0 13080 236 661336 2 16777596 -530786634

Hat tip to #melpomene for working through the details in the main comments.
Op, you're iterating over the entire range of the array regardless of the availability of input data. I suggest you do the following so the results are less random in appearance:
initialize the values in the 2D array to zero.
limit the input samples to the quantity you're expecting, and not to exceed the size of the array in either dimension.
In your post, you're showing the value of 3 in the first line of the input file. What does that mean -- 3 lines, 3 samples, or 3 samples for each of the 3 lines?
Since the input file has 3 samples per line, I'm guessing the initial value in the data file represents the samples per line where the values for each line are assigned to an individual inner array.
Without deviating too much from your post, consider the following:
// clear the array for easier diags
for (int n = 0; n < MAX_SIZE; n++)
for (int m = 0; m < MAX_SIZE; m++)
square[n][m] = 0;
int cols;
inFile >> cols; // first line of data file indicating the samples in each row
if (cols > MAX_SIZE) // don't exceed the size of the inner array
cols = MAX_SIZE;
for (int i = 0; i < MAX_SIZE; i++)
{
for(int j = 0; j < cols; j++)
{
if (!(inFile >> square[i][j])) // read until EOF
{
i = MAX_SIZE; // force outer loop to terminate since break only affects the inner loop.
break;
}
}
}
See How does ifstream's eof() work?

Related

i want to print no in 2d array by taking inputs but it will give wrong output

i am using vectors and i want to print same output as per the input by using the exact method in the code
trying to using 2 d vectors
//the cause of the error is the while j loop part
i mark it in the code
#include <bits/stdc++.h>
using namespace std;
// vector<int> dynamicArray(int *n,int *q)
// {
// }
int main()
{
int n, size, a;
cin >> n >> size;
vector<vector<int> > q;
// vector<int>q;
vector<int> q1;
for (int i = 0; i < size; i++) {
int j = 3;
// here error occurs
while (j > 1) {
cin >> a;
q1.push_back(a);
j--;
}
q.push_back(q1);
}
for (int i = 0; i < q.size(); i++) {
for (int j = 0; j < 3; j++) {
cout << q[i][j];
}
cout << endl;
}
return 0;
}
// here are the inputs
2 5
1 0 5
1 1 7
1 0 3
2 1 0
2 1 1
expected output
1 0 5
1 1 7
1 0 3
2 1 0
2 1 1
//here are the output
resulting output
100
105
105
105
105
I think that your code has 2 bugs in it. Firstly, you are not clearing vector q1 after every processed line, thus your code is pushing to q vector with the same prefix of values every time and that's why the output is the same line repeated multiple times.
Secondly, i think that you are trying to read 3 elements in every line but currently because of condition while(j > 1) you are reading only 2 elements. Try to change it to while(j > 0).

C++ matrix - Get number of columns where the lowest value is in the same row as the highest value in the columns after it

I'm writing a program in C++ where the inputs are N (the number of villages/rows), M (the number of days/columns) and an H[N][M]
matrix where I individually input the temperatures (min -50, max 50).
The output should be the total number of days when the village with the lowest
temperature has the highest forecast temperature, and after that the number (column) of these days in ascending order.
So if I input something like this:
3 5
10 15 12 10 10
11 11 11 11 20
12 16 16 16 20
The output should be:
2 2 3
Or input:
3 3
1 2 3
1 2 3
1 2 3
Output:
2 1 2
My approach was to first store the minimum temperatures and maximum forecast temperatures of each day into two separate arrays and
then writing a for loop where I check each village day by day if they contain both the minimum value on the given day and maximum forecast temperatures from that day on.
I have the following code:
#include <iostream>
const int maxarr = 1000;
int H[maxarr][maxarr];
using namespace std;
void read(int N, int M, int t[maxarr][maxarr]);
void count(int N, int M, int t[maxarr][maxarr]);
int main()
{
int N;
int M;
cout<<"Number of villages? ";
cin>>N;
cout<<"Number of days? ";
cin>>M;
read(N,M,H);
count(N,M,H);
return 0;
}
void read(int N, int M, int t[maxarr][maxarr])
{
for(int i = 0; i < N ; i++)
{
for(int j = 0; j < M ; j++)
{
cin>>t[i][j];
}
}
}
void count(int N, int M, int t[maxarr][maxarr])
{
int mintemparr[maxarr];
int maxtemparr[maxarr];
int mintemp;
int maxtemp;
int days[maxarr];
int cnt = 0;
for(int j = 0; j<M; j++)
{
mintemp = 51;
for(int i = 0; i<N; i++)
{
if(t[i][j]<mintemp)
{
mintemp = t[i][j];
}
mintemparr[j] = mintemp;
}
}
for(int i = 0; i < M-1; i++)
{
maxtemp = -51;
for(int j = 0; j < N; j++)
{
for(int k = i+1; k < M; k++)
{
if(t[j][k]>maxtemp)
{
maxtemp = t[j][k];
}
}
maxtemparr[i] = maxtemp;
}
}
for(int i = 0; i < M-1; i++)
{
for(int j = 0; j < N; j++)
{
for(int k = i+1; k < M; k++)
{
if(t[j][i] == mintemparr[i])
{
if(t[j][k] == maxtemparr[i])
{
days[cnt] = i+1;
cnt++;
//tried an i++ here, didn't work as intended
}
}
else
{
j++;
}
}
}
}
cout<<cnt<<" ";
for(int i = 0; i < cnt; i++)
{
cout<<days[i]<<" ";
}
}
There are some instances where it works perfectly, for example with the first input it's output is as it should be. But with the
second input I get
6 1 1 1 2 2 2
and a longer (1000x1000) input, which I obviously can't copy here also gives wrong results.
How could I make this code work as intended?
The reason why you're getting 6 1 1 1 2 2 2 for the second example is that you're not stopping to check whether a particular day fulfils the condition once you have found that it does. Thus you find that on day 1 the condition is fulfilled for village 1, village 2 and village 3 (the first three 1s in the result), and then the same happens for day 2.
From the comment
tried an i++ here, didn't work as intended
I guess you already identified that problem and the i++ was intended to prevent rechecking the same day again. However, as you noticed, that alone doesn't work - the reason here is that when skipping ahead to the next day you need to ensure that for that day checking the condition again starts with village 1 and the search for the highest temperature needs to begin from the start as well.
To do so, just add
++i; // carry on with the next day
j = 0; // start with the first village in the next iteration
k = i; // search for the highest temperature beginning from day i + 1
// note that at the end of the loop body `k` will be incremented
// so we need to use `k = i` instead of `k = i + 1` as in the loop-initializer here.
after cnt++ in place of the comment I quoted above.
With this change one gets the output you described in the question for both cases, as you can see here.
Given the input you uploaded to zippyshare I believe that the output for the second example should indeed be 3 1 2 3 instead of 2 1 2. Luckily the code is easy to change to accomodate that: Just replace all k = i + 1s by k = i and change the newly added k = i to k = i - 1 so that searching for the highest forecasts includes the present day.

concatenating arrays, array 1 memory gone C++

Program consists of array1[20] and array2[40] from input files. Array1 is then added on to the end of array2 (after which they will be sorted chronologically, but I havent gotten there yet bc I am stuck on this). The final result will be printed; I did not include this portion of the code nor the code for inputing files to make it easier for you to read :) thanks for the help.
The code yeilds no errors. The input is number 1 through 20 on both input files and the output reads
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 135062784 135305664 134511120 135308884 6 0 6 16 135303844 134511520 134511136 134957510 135308884 135111932 135120188 0 134511156 135303952 134511168 134805750
int readSortedArray (int array[20], int count, istream& infile)
{
count = 0;
while( (count < 20) && (infile >> array[count]) )
{
count++;
}
return count;
}
int main ()
{
int array[20], array1[20], array2[40];
int count, count1, count2, x;
count1 = readSortedArray(array1, count1, infile1);
count2 = readSortedArray(array2, count2, infile2);
for (int i=1; i < count1 + 1; i++ )
{
array1[i - 1] >> array2[count2 + i];
}
return 0;
}
Seems the for loop in the main function should be this (i should start at 0). And make sure infile2 really contains what you think it contains.
for (int i=0; i < count1; i++ )
{
array2[count2 + i] = array1[i];
}

Why reading integers from file into a 2d vector is resulting all values to be zero?

I am trying to read a matrix of integer values from a text file into a 2d vector.
Input Data:
4 5
0 -0.5 -3 -1 -4
40 1 1 1 1
10 -2 -1 1 1
10 0 1 0 -1
My code:
ifstream InFile("Simplex_EX1.txt");
if (!InFile.is_open())
cout << "File could not be opened correctly";
vector<vector<int>> MyData;
int Rows, Columns;
InFile >> Rows >> Columns; // read first line - working
MyData.resize(Rows);
for (int i = 0; i < Rows; i++)
MyData[i].resize(Columns);
for (int i = 0; i < Rows; i++)
for (int j = 0; j < Columns; j++)
InFile >> MyData[i][j]; // read the rest - not working
InFile.close();
So I successfully read the first line, hence I resize the vector correctly. However, final vector is just zeros. Could any one tell me what am I doing wrong? Please and thanks
You are trying to read a floating point number -0.5 into an integer, which fails. Once the stream fails it will not read anything else until the error is cleared.

How to write multiple columns in a loop in c++?

Suppose I have a loop:
for(int i=1; i<=1024; i++)
I want to fill a file with 128 columns (not rows!), so the first column contains numbers from 1 to 8, second from 9 to 16 and so on and so forth.
The items for each columns are just 8i to 8i+7. You can write mutiple loops.for(int i = 0; i< 128;i++)
for(int j = 0; j <8;j++)
int k = 8* i+ j;
void write_in_file( ofstream &fout, int start){
for(int i = 1; i <= 128; i++){
fout<<start <<"\t";
start+=8;
}
fout<<"\n";
}
int main(){
ofstream fout;
fout.open("out.txt");
for(int i=1;i<=8;i++){
write_in_file(fout,i);
}
}
Explanation:
As we need 8 rows so we call function write_in_file 8 times. Each time function write_in_file writes 128 entries in the file.
The simplest way is to make two loops - the first by lines and nested by columns - and then calculate numbers with easy math expression.
E.g.:
for(int line = 0; line < 8; line++)
{
for( int col = 0; col < 128; col++)
{
cout << setw(5) << line + col * 8 + 1;
}
cout << endl;
}
setw() has parameter 5 to make identical width for colums with numbers from 1 to 1024
EDITED:
If you want to use only one for loop and exact as you give in the question, you can use more complicated math expressions.
First, let's calculate number of line as (i-1) / 128 (numbers start from 0) and number of column as (i-1) % 128 (numbers from 0 to 127). And now you can make the following loop with additional new-line-conditional output:
for(int i=1; i<=1024; i++)
{
cout << setw(5) << ( 1 + 8 * ((i-1) % 128) ) + ( (i-1) / 128 );
if( i % 128 == 0 ) // new line once per 128 numbers
cout << endl;
}
Of course if you want to make file, you should do something with the output - redirect standard output to file or change cout to other stream.