Hi, I'm trying to send an array of data to a .txt file, and after a couple days am just rewriting code I wrote days ago.

I have an array of ints that I want to send to file in three columns

outputFile.open("sorted.txt");

    for(int i = 0; i < size; i++)
    {
        if(i % 3 == 0)
        {
            outputFile << " Pos# " <<i <<" : " << id[i] << " " << setprecision(4) << showpoint << ave[i] << " :" <<  endl;
        }
        else
        {
            outputFile << " Pos# " <<i <<" : " << id[i] << " " << setprecision(4) << showpoint << ave[i] << " :";
        }
    }

outputFile.close();

I know why this is happeneing I just can't seem to think of a way to get three coloumns to print, I always run into trouble with the beginning few because 0 mod 3 is 0. I have the feeling I'm barking up the wrong tree.

This output is the closest I've gotten:
Pos# 0 : 9002 98.57 :
Pos# 1 : 1012 97.00 : Pos# 2 : 3199 97.00 : Pos# 3 : 9518 97.00 :
Pos# 4 : 1222 97.00 : Pos# 5 : 8928 97.00 : Pos# 6 : 4751 97.00 :
Pos# 7 : 4770 97.00 : Pos# 8 : 3939 97.00 : Pos# 9 : 3333 97.00 :
Pos# 10 : 8280 97.00 : Pos# 11 : 3434 97.00 : Pos# 12 : 1422 97.00 :
Pos# 13 : 2000 93.57 : Pos# 14 : 1919 93.43 : Pos# 15 : 6621 92.14 :
Pos# 16 : 5123 90.29 : Pos# 17 : 3993 90.29 : Pos# 18 : 9393 90.14 :
Pos# 19 : 4012 87.57 : Pos# 20 : 7655 86.29 : Pos# 21 : 6037 86.00 :
Pos# 22 : 7714 85.00 : Pos# 23 : 7880 84.71 : Pos# 24 : 9191 83.29 :
Pos# 25 : 5677 82.71 : Pos# 26 : 2012 81.57 : Pos# 27 : 8480 80.14 :
Pos# 28 : 9088 79.86 : Pos# 29 : 1412 77.43 : Pos# 30 : 3228 77.29 :
Pos# 31 : 5325 77.29 : Pos# 32 : 7788 76.57 : Pos# 33 : 1219 76.00 :
Pos# 34 : 1010 75.86 : Pos# 35 : 6658 74.57 : Pos# 36 : 9999 64.43 :
Pos# 37 : 6786 58.43 : Pos# 38 : 6547 56.86 : Pos# 39 : 1234 32.29 :
Pos# 40 : 3993 10.00 :

Try something like:

for (int i = 0; i < size; ++i) {
   outputFile << " Pos# " <<i <<" : " 
              << id[i] << " " 
              << setprecision(4) << showpoint << ave[i];
   if (i > 0 && 0 == i % 3) {
      outputFile << std::endl;
   } else if (i < size - 1) {
      outputFile << " :";
   }
}

The size - 1 check is to ensure you don't leave a trailing " :" after the last item.

Edited 3 Years Ago by L7Sqr

Thanks, but my problem is just getting the three columns. I always end up with an entire entry by itself in the first row, or a row of four entries, or some other incorrect configuration. The colons are just folderal demarking the end of an entry.

Pos# 3 : 9518 97.00 :

is an example of 1 whole entry.

At the top I got swing'n single entry 0 by itself. I just can't seem to get three entries per line, except the last line, if there aren't enough entries left over. The problem in the case above is that index 0 is 0 which mod 3 is 0 so I gety an endl. The problem with just sending endls alone into the file is that they mess with the index count so I end up with ":endl"s instead of the entries themselves, that why I just slapped them on to the end of every third entry. This is a simple problem but I can't for the life of me see the solution.

Edited 3 Years Ago by mixelplik

Did you look at the code I provided? Consider the check

if (i > 0 && 0 == i % 3)

That eliminates the problem you were having with the first row. In addition I eliminated some of the code duplication you had.

I understood your problem; I was simply giving you a solution that attempted to avoid introducing another problem in the process.

Yeah, I was clarifying because I wasn't sure how clear my original post was, I wrote it while frustrated. Unfortunately your suggestion was something had I already tried, and it returns one of the many infuriatingly so "close but so far" configurations this one being 4 columns at the top then it goes into columns of 3. Thanks though, your responses are appreciated.

Hi,

I have a solution for you, the issue is that you are trying to detect the first row and do something on that. i find that its easier to detect the end of the row and insert a new line there. I have fully commented my code so check it out and adjust it to your application as necessary. Note that like L7Sqry mentioned: code duplication for no reason is a bad idea. Instead try to separate the common part of both the if and else case and always execute it first then in the if / else only have code that is different.

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
   /* open file for writing ( overwrite contents ) */
   ofstream outFile;
   outFile.open( "output.txt", std::ofstream::out );

   /* create an array of size k_nArraySize and initialise it */
   const size_t k_nArraySize = 9;
   int* pIntArray = new int[k_nArraySize];

   for( size_t n = 0; n < k_nArraySize; n++ )
   {
      pIntArray[n] = n * n;
   }

   const size_t k_nValuesPerRow = 3; /* define how many columns */

   /* do output */

   /* loop from one end of the array to the other */
   for( size_t n = 0; n < k_nArraySize; n++ )
   {
      /* output this value from the array to the file */
      outFile << "[pos: " << n << " val: " << pIntArray[n] << "] ";

      /* output this value from the array to cout for easy viewing */
      cout << "[pos: " << n << " val: " << pIntArray[n] << "] ";


      /* check if this is the last value for this row
       *
       * if we want k_nValuesPerRow then using an index starting at 0 we have
       * to take one away to get the last value.
       *
       * so if we wanted 3 cols we would have array index 2, 4, 6 ,.. etc as
       * the array index of the last column for this row.
       *
       * This if checks for that condition and upon it being met it inserts a
       * new line to start the next row
       *
       */
      if( ( k_nValuesPerRow -1 )  == ( n % k_nValuesPerRow ) )
      {
         outFile << endl;
         cout << endl;
      }
   }

    return 0;
}

Oh, I'm terribly sorry. I had an error in my example; the newline should go before the printing code. Something like:

for (int i = 0; i < size; ++i) {
   if (i > 0 && 0 == i % 3)
      outputFile << std::endl;

   outputFile << " Pos# " <<i <<" : " 
              << id[i] << " " 
              << setprecision(4) << showpoint << ave[i] << " : ";

}

I've tested this and I believe it is what you wanted. Shows me for posting untested code...

This article has been dead for over six months. Start a new discussion instead.