Reputation: 375
I have a file with lines of integers. I want to read each line into a slot in my array. I have the code below, but it does not work. I'm not sure if I'm on the right track.
void Read_Save() {
ifstream in;
int arr[100];
string line;
in.open("file.txt");
while (in.peek() != EOF)
{
getline(in, line, '\n');
strcpy(arr, line.c_str());
}
in.clear(); in.close();
}
Upvotes: 1
Views: 1183
Reputation: 63481
There are several ways to parse the integer value out of the string.
First, let's fix your loop:
int pos = 0;
while( std::getline(in, line) && pos < 100 )
{
int value = 0;
// Insert chosen parsing method here
arr[pos++] = value;
}
Here is a non-exhaustive list of common options:
Use std::strtol
// Will return 0 on error (indistinguishable from parsing actual 0)
value = std::strtol( line.c_str(), nullptr, 10 );
Use std::stoi
// Will throw exception on error
value = std::stoi( line );
Build a std::istringstream
and read from it:
std::istringstream iss( line );
iss >> value;
if( !iss ) {
// Failed to parse value.
}
Use std::sscanf
if( 1 != std::sscanf( line.c_str(), "%d", &value ) )
{
// Failed to parse value.
}
Now, note the bounds-test on the loop checking pos < 100
. This is because your array has a storage limit. Actually, you have also overridden the global one with a local one in Read_Save
, thus hiding it with a smaller array that will be lost when the function finishes.
You can have an arbitrary-sized "array" (not actually an array) using other container types provided by the standard library. Useful ones that provide random access are std::vector
and std::deque
. Let's use the vector and change the definition of Read_Save
to be a bit more useful:
std::vector<int> Read_Save( std::istream & in )
{
std::vector<int> values;
std::string line;
for( int line_number = 1; getline( in, line ); line_number++ )
{
try {
int value = std::stoi( line );
values.push_back( value );
}
catch( std::bad_alloc & e )
{
std::cerr << "Error (line " << line_number << "): Out of memory!" << std::endl;
throw e;
}
catch( std::exception & e)
{
std::cerr << "Error (line " << line_number << "): " << e.what() << std::endl;
}
}
return values;
}
And finally, the call becomes:
std::ifstream in( "file.txt" );
std::vector<int> values = Read_Save( in );
Upvotes: 2
Reputation: 598001
You cannot use strcpy()
to convert a string to an integer. You can use std::strtol()
or std::stoi()
, or even a std::istringstream
, eg:
int arr[1000];
void Read_Save() {
ifstream in;
string line;
in.open("file.txt");
int index = 0;
while ((index < 1000) && (getline(in, line)))
{
if (istringstream(line) >> arr[index])
++index;
}
}
Upvotes: 1
Reputation: 3911
The best thing to do in your case is to use std::vector
. The code would look like this:
void Read_Save()
{
std::ifstream in("file.txt");
int value;
std::vector<int> arr;
while (in >> value)
arr.push_back(value);
for(int i(0); i < arr.size(); i++)
std::cout << arr[i] << ", ";
std::cout << std::endl;
in.close();
}
Upvotes: 0