I'm trying to read from a file and create an array of structs to hold the information from the file. I cannot figure out how to do it. I'm not even sure where to start.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
void readFile(string filename, AccessRecord records[500])
{
ifstream fin(filename); //open file
if (fin.fail()) //check for fail
return 0;
while (fin >> records[500]) //this is where I run into trouble
{ //I know this is all wrong, I just
int i = 0; //don't know what I am supposed to do
fin >> records[i] //to get the info into the array,
i++; //or how to break it into the different
} //parts of the struct
fin.close(); //close file
}
Do you realize that trying to use records[500] is accessing the array out of bounds?
Perhaps something more like:
1 2 3 4 5 6 7 8 9 10 11 12 13
void readFile(const string& filename, AccessRecord records[500]) // Note the changes to the string.
{
ifstream fin(filename); //open file
int i = 0;
// If the file fails to open correctly this loop will also fail and nothing will be added to the array.
// Also no need to manually close the file, let the destructor do it's job of closing the file.
while (i < 500 && fin >> records[i]) // Make sure you don't access the array out of bounds.
{
i++;
}
}
A couple of problems: Line 1: You're passing records by value, so readFile is operating on a copy of the array. Updates made to records by readFile will be lost when readFile exits.
Line 7: You're trying to read into the 501st element of the array, which is out of bounds.
Arrays start at 0, so the valid elements are 0 - 499.
Line 9: You're resetting i to zero every time through the loop. Consequently, line 10 will only ever read into records[0]. BTW, i needs to be outside the loop.
1 2 3 4 5 6 7 8 9 10
void readFile(string filename, AccessRecord * records)
{ int i = 0;
ifstream fin(filename); //open file
i f (fin.fail()) //check for fail
return 0;
while (fin >> records[i])
{ i++;
}
fin.close(); //close file
}
okay, I fixed the string parameter, and added the i < 500, I also realized that I was resetting i to 0 on every loop, so I moved that outside the loop. It still isn't doing what it needs to do though. I think there is something fundamental that I'm missing.
A couple of problems:
Line 1: You're passing records by value, so readFile is operating on a copy of the array. Updates made to records by readFile will be lost when readFile exits.
Wrong. He's passing the array via a pointer which is how you always pass arrays to functions. All updates made in the function will be reflected in the calling function. By the way that pointer is what is passed by value (a copy) so any modifications made to where the pointer points will be lost when the function returns.
I think there is something fundamental that I'm missing.
Show your current code. Are you still trying to read the file twice?
This is what I currently have. I've always passed arrays this way in the past, and it has always worked. I don't really want to use a pointer if it can be avoided. They confuse me to no end.
1 2 3 4 5 6 7 8 9 10 11 12
void readFile(const string & filename, AccessRecord records[500])
{
ifstream fin(filename); //open file
if (fin.fail()) //check for fail
return;
int i = 0;
while (( i < 500) && (fin >> records[i]))
{
i++;
}
fin.close(); //close file
}
currently when I try to compile it it is spitting out pages worth of errors, and I can't figure out why. I know the problem is somewhere in this function, because it has no problem when it's blocked out. Specifically it's complaining about the while line, but I can't figure out what exactly the problem is.
currently when I try to compile it it is spitting out pages worth of errors, and I can't figure out why.
If you're getting compile error then post those errors, all of them exactly as they appear in your development environment.
I know the problem is somewhere in this function,
How do you know? Are your error messages telling you that the problem lies within this function? Do you know that the error messages should be telling the exact line number where it detects the problem?
because it has no problem when it's blocked out.
This doesn't mean that the problem is definitely inside the function, although it is likely, it depends on what your error messages are actually saying.
Edit: By the way what exactly is an "AccessRecord"? It would be helpful if you posted a small complete program that illustrates the problems.
I tried to post the program, and the error codes, but go figure... it was too long.
basically this program is supposed to read the access records from a file, including a user name, files accessed by that person, and a timestamp of when they were accessed. I need to be able to display just the records that fall between a certain time period. I made a struct called AccessRecords to hold each line of the file, and I need an array to hold all of them. I just don't know how to get them from the file into the array of structs.
I won't post all of the errors, but here is the first bunch of them:
assign02.cpp: In function ‘void readFile(const string&, AccessRecord*)’:
assign02.cpp:90:26: error: no match for ‘operator>>’ (operand types are ‘std::ifstrea
while (i < 500 && fin >> records[i])
~~~~^~~~~~~~~~~~~
In file included from /usr/include/c++/8/iostream:40,
from assign02.cpp:16:
/usr/include/c++/8/istream:120:7: note: candidate: ‘std::basic_istream<_CharT, _Traitstd::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istrea
operator>>(__istream_type& (*__pf)(__istream_type&))
^~~~~~~~
/usr/include/c++/8/istream:120:7: note: no known conversion for argument 1 from ‘Acasic_istream<char>::__istream_type&)’ {aka ‘std::basic_istream<char>& (*)(std::basic_
/usr/include/c++/8/istream:124:7: note: candidate: ‘std::basic_istream<_CharT, _Traitstd::basic_istream<_CharT, _Traits>::__ios_type& (*)(std::basic_istream<_CharT, _Traihar>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>;ar>]’
operator>>(__ios_type& (*__pf)(__ios_type&))
^~~~~~~~
/usr/include/c++/8/istream:124:7: note: no known conversion for argument 1 from ‘Ac_istream<char>::__ios_type&)’ {aka ‘std::basic_ios<char>& (*)(std::basic_ios<char>&)’
/usr/include/c++/8/istream:131:7: note: candidate: ‘std::basic_istream<_CharT, _Traitstd::ios_base& (*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits<cic_istream<char>]’
operator>>(ios_base& (*__pf)(ios_base&))
assign02.cpp: In function ‘void readFile(const string&, AccessRecord*)’:
assign02.cpp:90:26: error: no match for ‘operator>>’ (operand types are ‘std::ifstrea
while (i < 500 && fin >> records[i])
Okay so look at the first error, and answer the question I posed above about AccessRecord.
I tried to post the program, and the error codes, but go figure... it was too long.
That is why I said to post a small complete program that illustrates your problem.
You need to post the definition of the AccessRecord type so we can see what that type actually is.
Okay do you realize that unless you have overloaded the insertion operator>> the compiler doesn't know how to "read" that structure using the operator?
yeah, I know it doesn't know how... I don't know how either. That's what I'm asking for help with! haha! I know what I have wouldn't work, I just don't know where to go from here
Depending on how the data is stored on the file, the pseudocode for this goes something like this.
open the file
Loop:
create a temp of type AccessRecord
read a line from file
parse line into attributes
set temp to these attributes
assign temp to next vacant item in array
Loop until there are no more lines/attributes on file
close the file
You should be able to write and test code sequentially through this to avoid all this back and forth hole digging. Without a psedocode plan you are chewing up a mountain of time.
Just tick off each item in the plan as it develops through testing each component sequentially. Don’t proceed until that bit works.
Silence reigns so this might help seeing the full picture you present to me. Pls not for arrays you pretty much can't get away from pointers. (All you have to do is add '*' to the front of the array name, and specify the array size.)