Accessing a file using an array

I'm not even sure I asked the question correctly. This is for an assignment, but I don't want help with the whole thing, at least not yet. It's our longest program yet and I want to try and figure it out. I'm just stuck about this.

Info about the assignment: We have to put songs on a CD. Each song needs to be between 60-600 seconds, inclusive. We then convert the seconds to minutes and seconds. After each song is read, we need to display the song number, the song time, the total time on the CD, and at the end, the amount of minutes and seconds left on the CD. Any song not in rage is not shown on the screen, but when writing to an output file, an invalid error shows.

I was wondering, how would I use an array to access the contents of a file?

She wants the file opened using its own function, so the file's open already. There are 11 numbers in the file, so 11 elements in the array, all initialized.

This is what I have right now, relative to my question:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void readData(int song[], int size)
{
    int songNumber = 1; //counter variable to step through each song
    int songSeconds; // original seconds of each song (310)
    int songMin; // minutes of each song (5:)
    int songSec; // seconds of each song (:10)
    int totalSeconds; // total original seconds after each song
    int totalMin; //total song minutes after each song
    int totalSec; //total song seconds after each song

    while (inputFile)
    {
        //read each song's seconds from the file
        inputFile >> songSeconds;

        //validate data
        if(songSeconds >= 60 && songSeconds <= 600)
        {
           // convert original seconds to minutes and seconds after each song
           songMin = songSeconds / 60;
           songSec = songSeconds % 60;

           //updating total original seconds after each song
           totalSeconds += songSeconds;

           //convert total original seconds to total minutes and seconds after each song
           totalMin = totalSeconds / 60;
           totalSec = totalSeconds % 60;

           cout << "\n" << songNumber << setw(10) << " " << songMin << setw(10) <<songSec<<setw(18)<<totalMin<<setw(10)<<totalSec;
           outputFile << "\n" << songNumber << setw(10) << " " << songMin << setw(10)<<songSec<<setw(18)<<totalMin<<setw(10)<<totalSec;

        }

    }


I may go ahead and make all of my variables global variables. I'm not sure which is better.

Am I using the array correctly? It feels like I'm missing something. It doesn't seem like the array is accessing anything.
Is the way I'm accessing the file correct (and writing to the output file)?
Last edited on
I think my while loop is wrong. Should it be:

while(songNumber < SONG_LENGTHS && inputFile >> song[songNumber])
Last edited on
Am I using the array correctly?

I don't see where your using the array anywhere in the code you supplied.

I may go ahead and make all of my variables global variables. I'm not sure which is better.

It's not better to use global variables, if that is your question. Global variables should be avoided as much as possible.

She wants the file opened using its own function, so the file's open already.

You really shouldn't be using global variables learn to pass the variables to and from your functions as required. IMO this function's signature should look more like:

void readData(ifstream& inputFile, ofstream& outputFile, int song[], int size)

Is the way I'm accessing the file correct (and writing to the output file)?

That's hard to tell without knowing what information is contained within the file and how the file is formatted, for the output it looks like you may be using the setw() function incorrectly, but even that depends on how you want to actually format the file. The easiest way to tell if you're writing to a file correctly is to look at the file with a text editor.


I don't see where your using the array anywhere in the code you supplied.


I put my array in the main function. Should I put it here instead? Here's how I wrote it:

1
2
const int SONG_LENGTHS = 11;
int songs[SONG_LENGTHS] = {310,482,601,259,983,273,567,-12,535,45,300};


You really shouldn't be using global variables learn to pass the variables to and from your functions as required. IMO this function's signature should look more like:

void readData(ifstream& inputFile, ofstream& outputFile, int song[], int size)


I'm not going to put global variables, if you say it's best to avoid them. We have to have our input file in its own function, per the instructions. I didn't realized I had to pass those as well.

About writing to the output file, I was asking if that's the way to do it? Have a separate statement for cout and outputFile? I'm not worried about what I wrote. This is all the first write-up. I haven't executed anything yet.
Last edited on
This is what the screen should look like, minus the song number 7 error. The song is too short, so it shouldn't be seen.

https://s15.postimg.org/4kn1ibh4r/capture4.jpg
This is my call to the readData function.

readData(songs, SONG_LENGTHS);

It's giving me the error, "could not convert '(int*)(& songs)' from 'int*' to 'std::ifstream'"

I don't understand what that means.

I took out the references to the input and output files from my function header (at least for now). It wouldn't work. I get this error when having the array name and size in the header.
Here's the code for my whole program. I can only get it to execute to my printHeader function. It shows on the screen, but nothing is written to the output file like it should.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;

//global variable
const int TOTAL_SPACE = 80;
int songNumber = 1; //counter variable to step through each song
int songSeconds; // original seconds of each song (310)
int songMin; // minutes of each song (5:)
int songSec; // seconds of each song (:10)
int totalSeconds; // total original seconds after each song
int totalMin; //holds total song minutes after each song
int totalSec; //holds total song seconds after each song
int remainSeconds; //total seconds left on the CD
int remainMin; //minutes left on the CD
int remainSec; //leftover seconds left on the CD
int invalidData;
ofstream outputFile("c:\\path_to_document\\songsOutput.dat");
ifstream inputFile;

//Function prototypes
void printHeader();
void openFile();
void printDetails(int);
void readData(int[], int);
void printResults();

int main()
{
    const int SONG_LENGTHS = 11;
    int songs[SONG_LENGTHS] = {310,482,601,259,983,273,567,-12,535,45,300};

    openFile();
    printHeader();
    readData(songs, SONG_LENGTHS);
    printResults();

    inputFile.close();
    outputFile.close();
    return 0;
}

void printHeader()
{
    cout << "\n " << " Song " << setw(20) << " Song Time " << setw(30) << " Total Time ";
    cout << "\n " << " Number " << setw(15) << " Minutes Seconds " << setw(30) << " Minutes Seconds \n\n";

    outputFile<<"\n " << " Song " << setw(20) << " Song Time " << setw(30) << " Total Time ";
    outputFile<<"\n " << " Number " << setw(15) << " Minutes Seconds " << setw(30) << " Minutes Seconds \n\n";
}

void openFile()
{
    inputFile.open("c:\\path_to_document\\songs.dat"); //add path to file
}

void readData(int song[], int size)
{
    while(songNumber < size && inputFile >> song[songNumber])
    {
        //read each song's seconds from the file
        inputFile >> songSeconds;

        //validate data
        if(songSeconds >= 60 && songSeconds <= 600)
        {
            // convert original seconds to minutes and seconds after each song
            songMin = songSeconds / 60;
            songSec = songSeconds % 60;

            //updating total original seconds after each song
            totalSeconds += songSeconds;

            //convert total original seconds to total minutes and seconds after each song
            totalMin = totalSeconds / 60;
            totalSec = totalSeconds % 60;

            cout << "\n" << songNumber << setw(10) << " " << songMin << setw(10)<<songSec<<setw(18)<<totalMin<<setw(10)<<totalSec;
            outputFile << "\n" << songNumber << setw(10) << " " << songMin << setw(10)<<songSec<<setw(18)<<totalMin<<setw(10)<<totalSec;

            songNumber++;
        }
        else
        {
            //increment invalid data
            invalidData++;

            //write invalid data to file
            outputFile<<"\nInvalid Data";
        }

        //calc remaining time on CD
        remainSeconds = 4800 - totalSeconds;

        //convert remaining time to minutes and seconds
        remainMin = remainSeconds / 60;
        remainSec = remainSeconds % 60;
    }
}

void printResults()
{
        cout << "There are "<<remainMin<<" minutes and "<<remainSec<<" seconds of space left on the 80 minute CD\n";
        outputFile << "There are "<<remainMin<<" minutes and "<<remainSec<<" seconds of space left on the 80 minute CD\n";
}
She wants the file opened using its own function, so the file's open already.


Right. You do realize she's going to see right through this:

1
2
3
4
5
6
ifstream inputFile;

void openFile()
{
    inputFile.open("c:\\path_to_document\\songs.dat"); //add path to file
}


As just being the equivalent of this:

 
ofstream outputFile("c:\\path_to_document\\songsOutput.dat");


Yes? I mean, you did exactly the same thing, except you decided to be clever and pass it to a function because she told you to. Let's not kid ourselves: openfile is really just a roundabout way of doing exactly what you did with outputfile. Maybe try something along the lines of:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ifstream get_infile(const string& s)
{
     ifstream ifs{s};
     if(!ifs){
          cerr << "Cannot locate file by that name...\n";
     }
     
     return ifs;
}

//And then you can do something like...
cout << "Enter a file name: ";
string filename;
cin >> filename;
ifstream inputfile = get_infile(filename);


And if you don't want to do that, you can just hardcode the file name into a string and pass that. But I definitely wouldn't just pass it to a single line void function that assigns to a global variable. For what that's worth you may as well just hardcode it from the start.
...I have no idea what you're talking about.

Regardless, I've since figured out the problem with my code and everything is executing correctly.

Also, we aren't coding the way you did, so that would've been no help to me.
Also, we aren't coding the way you did, so that would've been no help to me.


Yeah, I'm feeling really good about my decision to try and lend you a hand. Not regretting that in the slightest.
And I'm feeling really good about figuring it out before some smart ass decides to comment. Not regretting that in the slightest. (Except I'm really not.)
What is your current problem now, MikeSW?
And I'm feeling really good about figuring it out before some smart ass decides to comment. Not regretting that in the slightest. (Except I'm really not.)


Good to know. Now all you're left with is some busted ass code, fully 22% of it subtracting spaces, comments, and braces comprising global variables, an inability to follow or understand instructions given, and you somehow don't comprehend function calls. Other than that though, well done! Should come in handy when you're repeating the class.
The code above isn't my final code, but thanks. Have a great night. :)

@SakurasouBusters Nothing anymore. I've since fixed everything. Thanks anyway.
Topic archived. No new replies allowed.