-3

File info:

6 10

0 1 0 1 0 1 1 1 1 1

0 1 1 1 1 1 1 1 1 0

0 0 1 1 1 1 1 1 1 0

0 1 1 1 1 0 1 0 1 1

0 1 1 1 1 1 0 1 1 1

0 1 1 1 0 1 1 0 1 1

The script:

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    int x; int y;   
    int masyvas[x][y];  // masyvas is 2D array

    int sum = 0;

    ifstream D ("Duomenys.txt"); // the files name

    D >> x >> y; // x and y is 6 and 10
    // The scanning/reading 
    for (int i = 1; i < x + 1; i++)
    {
        for (int j = 1; j < y + 1; j++)
        {           
            D >> masyvas[i][j]; 
        }       
    }   
    // the printing
    for (int i = 1; i < x + 1; i++){
        for (int j = 1 ; j < y + 1; j++){

            cout << masyvas[x][j] << "  ";
            sum = sum + masyvas[i][j];                              
        }
        cout << sum << endl;            
        sum = 0;
    }   
    D.close();  

    return 0;
}

Now when I test this file ( compile it ) getting no errors but I get this.

Result:

0 1 0 1 0 1 1 1 1 1 7

0 1 0 1 0 1 1 1 1 1 7

0 1 0 1 0 1 1 1 1 1 7

0 1 0 1 0 1 1 1 1 1 7

0 1 0 1 0 1 1 1 1 1 7

0 1 0 1 0 1 1 1 1 1 7

Now, why does it repeat? Where am I doing it wrong? And did I do right with the rows? ( trying to sum them up)

The wanted result:

0 1 0 1 0 1 1 1 1 1 7

0 1 1 1 1 1 1 1 1 0 8

0 0 1 1 1 1 1 1 1 0 7

0 1 1 1 1 0 1 0 1 1 7

0 1 1 1 1 1 0 1 1 1 8

0 1 1 1 0 1 1 0 1 1 7

How can I achieve that?

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Kataroo
  • 7
  • 1
  • 5
    This is not allowed `int masyvas[x][y];` as `x` and `y` must be known at compile time. I'd suggest instead using `std::vector` – Cory Kramer Jul 24 '17 at 17:27
  • 2
    Besides c++ code isn't a script, did you step through your code line by line with the debugger already? What did you observe when doing so? – user0042 Jul 24 '17 at 17:28
  • You have an off by one error. Arrays indexes start at 0 and run up to but not including their size. – NathanOliver Jul 24 '17 at 17:29
  • @CoryKramer What's the diffrence between vector and array ? – Kataroo Jul 24 '17 at 17:31
  • @Kataroo https://stackoverflow.com/questions/15079057/arrays-vs-vectors-introductory-similarities-and-differences – Cory Kramer Jul 24 '17 at 17:33
  • 1
    it is also exceptionally helpful for `x` and `y` to be assigned values before being used to allocate storage. – user4581301 Jul 24 '17 at 17:35
  • 1
    Fyi, if the entire goal of all of this is to simply output each line, formatted as-read, then a summation, then repeat, there is no reason for any arrays or vectors in this code *at all*. Just read the size info, then as you process each 'row', output it's values and, when finished, an accumulated summation and a newline. Do that for each line and I think you're done. – WhozCraig Jul 24 '17 at 17:41
  • Well, sorry for asking a terrible question...i didnt know that or didnt understand it till now....sorry. – Kataroo Jul 24 '17 at 17:44

3 Answers3

3

There is a few problems with your code. First, x and y are not initialized before the line:

int masyvas[x][y];  // masyvas is 2D array

Then, when you read into the array:

D >> masyvas[i][j];

the indices you use (i and j) range from 1 to x and from 1 to y. But arrays in C/C++ are 0-based, thus i and j should range from 0 to x-1 and 0 to y-1.

I would suggest that instead of loops and arrays, you use the C++ way: containers (vector) and iterators.

For instance, instead of calling "D >> masyvas[i][j]" y times, you can simply use

copy_n(istream_iterator<int>(input_data),
       cols,
       back_inserter(row));

This simply says that "cols" integers are read from input_data and then appended to the back of the vector called "row".

For output you can use a similar technique: the following line says that the entire "row" vector is copied to the output "cout", such that between each two elements there is a space:

copy(row.begin(), row.end(),
     ostream_iterator<int>(cout," "));

Finally, to compute the total of a row, we can use the function "accumulate" which does just that:

cout << accumulate(row.begin(), row.end(), 0) << "\n";

The complete code is below:

#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <numeric>
#include <vector>
int main(int argc, char *argv[])
{
    using namespace std;
    int rows, cols;
    ifstream input_data("Duomenys.txt");
    input_data >> rows >> cols;
    for(int i = 0; i < rows; i++)
        {
            vector<int> row;
            copy_n(istream_iterator<int>(input_data),
                         cols,
                         back_inserter(row));
            copy(row.begin(), row.end(),
                     ostream_iterator<int>(cout," "));
            cout << accumulate(row.begin(), row.end(), 0) << "\n";
        }
    return 0;
}
Mohammad Alaggan
  • 3,749
  • 1
  • 28
  • 20
  • @Eddge and user4581301 I updated the answer according to your appreciated feedback. Thank you. – Mohammad Alaggan Jul 24 '17 at 18:22
  • Good edit. Only complaint to raise now is there is no need for the `vector` at all, but its use is educational. – user4581301 Jul 24 '17 at 18:22
  • @user4581301 The integers read need to be both printed and accumulated. Other than using fancy iterators in C++03 or lambdas in C++11, it is not immediately clear to me how to do without an intermediate container. – Mohammad Alaggan Jul 24 '17 at 18:24
  • Thanks for the edit, contains a lot helpful information. – AresCaelum Jul 24 '17 at 18:29
  • From my read of the question, all OP needs to do is print the results, so for each row read, compute, and print. No need for storage. But like I wrote, good example of how a vector can be used and the tools available. – user4581301 Jul 24 '17 at 18:38
0

A few things to note:

  1. In your 'printing' for loops, you're cout'ing masyvas[x][j] with an x. Shouldn't that be masyvas[i][j] with an i?
  2. Arrays in C++ start with 0 and go up to arraySize - 1 but your for loops start at index 1 and go to arraySize + 1. Suppose I write a for loop like this:

    int array[10] = {1, 2, 3, 5, 8, 13, 21, 34, 55, 89};
    for (int x = 1; x < 10 + 1; x++) {
        cout << array[10] << " " << endl;
    }
    

    We get the first index in an array using 0, not 1. So instead of printing out the sequence of numbers in the array, it's going to start at the 1st index (2) and go until the 11th index (out of range) and crash my program.

  3. How is your array creation not giving you compiler errors? It does on mine. When you create an int, C++ isn't going to initalize it to 0 so you don't know what could be in it. As an example:

    int x;
    int y;
    cout << x << ", " << y << endl;
    

    This won't compile for me. It tells me that x contains -858993460. Imagine trying to create an array with that as one of the sizes. The two most basic solutions would be vector and dynamic arrays using the new operator.

Hope this helps.

Zach Alexander
  • 403
  • 4
  • 9
-3

I think your main problem here is your declaration of the 2d array:

int masyvas[x][y];

x and y are not known at compile time, you need to either use dynamic memory allocation, use something like std::vector, or set masyvass size to something larger than you'll need:

int masyvas[100][100];

Try that instead.

Stewart
  • 4,356
  • 2
  • 27
  • 59
  • 4
    Don't program by guessing. Use something that is bullet proof like a `std::vector`. – NathanOliver Jul 24 '17 at 17:33
  • .... and then you try to read a file that is 101 elements big and your program writes out of bounds and dies – Cory Kramer Jul 24 '17 at 17:34
  • based on the question, he's just learning the basics. Of course std::vector would be better, but I suspect that it's beyond the scope of this assignment. If X > 100, then just asssert or something – Stewart Jul 24 '17 at 17:34
  • 3
    Seeing as they are relatively new to the language why teach them bad practice? Teach them the correct way to do things so they don't develop bad habits. – Cory Kramer Jul 24 '17 at 17:35
  • To be fair with you all but this helped helped alot. – Kataroo Jul 24 '17 at 17:37
  • @Kataroo That helped you only half way. You should know as mentioned in other comments, that VLAs aren't c++ standard. Nevertheless you compiller seems to support them (otherwise you won't have been able to run your program at all). Your main problem was that you didn't set the values for `x` and `y` before doing the array allocation `int masyvas[x][y];`. That was the real problem, and this answer didn't solve it. And of course it's better to use a `std::vector>` to avoid the non standard VLA. – user0042 Jul 24 '17 at 17:48