how to read specific lines from a textile into variables
how to read specific lines from a textile into variables
I have been given a text file containing readings of sensors such as:
Temp1,17.8
Temp2,17.9
Temp1,18.1
Temp2,18.2
how can I store the numerical values into variables?
i have tried a lot of things, but can't get it to work.
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
double sumOfTemp;
int main ()
string filename;
string buffer;
string temp;
char apple;
char temp1[10000];
char temp2[10000];
double arr1[10000];
double arr2[10000];
int lineRead=0; //counter for number of lines read;
cout<<"Please enter a file: ";
cin>>filename;
ifstream infile(filename.c_str());
cout<<"before loop"<<endl;
while(infile.get(apple));
cout<<"beginning of loop"<<endl;
getline(infile,buffer);
int size=0;
size=buffer.length();
bool delFound=false;
for(int i =0; i<size; i++)
if (buffer[i]==',')
delFound=true;
if(delFound)
temp.append(buffer[i]);
cout<<"end of loop"<<endl;
cout<<"Temp value"<<temp<<endl;
cout<<"out of loop"<<endl;
this is what I have so far, but i'm 100% sure there must be a simpler method.
The final outcome of what I intend to do:
Write a C++ program that calculates the average temperature
in a room over a period of time based on the data from two IoT sensors.
Your program should first request the name of a temperature text file. A text file is provided that contains a number of sensor messages sent, with
each line representing a distinct message. Each message contains a sensor name and
a temperature value which are separated by commas. The program should read the
temperature data into a suitable data structure. The temperatures for sensor 1 should
then be added to a global sum total by the parent process, while a child process should
be spawned to add the temperatures for sensor 2 to the same global sum total. After
all the temperature samples have been processed, the average temperature should be
calculated and printed by dividing the sum total by the number of samples. Assume
that the specied text le is located in the same directory as your program. The average
temperature value should be formatted to two decimal places.
I have changed the code to this:
int main ()
string filename;
string buffer;
string temp;
char apple;
char temp1[10000];
//char temp2[10000];
//double arr1[10000];
//double arr2[10000];
int lineRead=0; //counter for number of lines read;
cout<<"Please enter a file: ";
cin>>filename;
ifstream infile(filename.c_str());
cout<<"before loop"<<endl;
while(infile.get(apple));
cout<<"beginning of loop"<<endl;
getline(infile, buffer, ',');
infile >> temp1;
// Just in case:
infile.ignore(10000, 'n');
getline(infile, buffer, ',');
infile >> temp1;
// Just in case:
infile.ignore(10000, 'n');
cout<<"end of loop"<<endl;
cout<<"Temp value"<<temp1<<endl;
cout<<"out of loop"<<endl;
but it still isn't saved to the temp1 variable.
std::string
char
For a foundation, search the internet for "c++ read file struct CSV".
– Thomas Matthews
Sep 2 at 20:46
I used strings and char, and then used arrays to try and solve the problem, this is where I am now
– Temulin
Sep 2 at 20:59
BTW, arrays don't have methods. The
temp.append
is a syntax error (unless you choose to use an array of classes that have append
method).– Thomas Matthews
Sep 2 at 21:01
temp.append
append
The semicolon indicating an empty while body
while(infile.get(apple));
is going to cause problems.– Eljay
Sep 3 at 13:30
while(infile.get(apple));
1 Answer
1
When given input that can be of records, I create a class to model the record:
class Record
public:
std::string source_name;
double temperature;
;
The next step I do is to overload operator>>
to input a record:
operator>>
class Record
//...
public:
friend std::istream& operator>>(std::istream& input, Record& r);
;
std::istream& operator>>(std::istream& input, Record& r)
std::getline(input, r.source_name, ',');
input >> r.temperature;
// Just in case:
input.ignore(10000, 'n');
return input;
After a Record
data structure is defined, then next step is to read in the data into a database:
Record
std::vector<Record> database;
Record r;
while (input_file >> r)
database.push_back(r);
At this point, all the data is in the database.
You can access the data in the database:
double temp1_sum = 0.0;
double temp2_sum = 0.0;
const size_t database_size = database.size();
for (size_t i = 0; i < database_size; ++i)
if (database[i].source_name == "Temp1")
temp1_sum += database[i].temperature;
if (database[i].source_name == "Temp2")
temp2_sum += database[i].temperature;
Using the above technique of searching the database, you can do things like calculate the average temperature, find minimum or maximum temperature, etc.
If the input method is not working, then adjust the operator>>()
method to read correctly. You may want to convert the source field to all lower case or all upper case after reading.
operator>>()
Edit 1: But I can't use std::vector
std::vector
If your programming class is not allowed to use std::vector
, you'll have to use dynamic arrays and adjust the capacity dynamically. Or you can hope that the input file contains less elements than your declared capacity.
std::vector
const size_t DATABASE_CAPACITY = 1000;
Record database[DATABASE_CAPACITY];
size_t database_size = 0;
Record r;
while (input_file >> r)
if (database_size < DATABASE_CAPACITY)
database[database_size] = r;
++database_size;
else
std::cerr << "Database capacity, " << DATABASE_CAPACITY << " exceededn";
break;
At this point, the variable database_size
will contain the quantity of records in the database.
database_size
Edit 2: But our class hasn't covered class
or struct
class
struct
If you can't model the data using a single class
or struct
, you'll have to use parallel arrays. One drawback to parallel arrays is that the data could get out of synchronization.
class
struct
size_t DATABASE_CAPACITY = 512;
std::string database_source_names[DATABASE_CAPACITY];
double database_temperatures[DATABASE_CAPACITY];
size_t database_size = 0;
std::string name;
while (std::getline(input_file, name, ','))
double temperature;
input_file >> temperature;
if (database_size < DATABASE_CAPACITY)
database_source_names[database_size] = name;
database_temperatures[database_size] = temperature;
++database_size;
else
std::cerr << "Database capacity of " << DATABASE_CAPACITY << " exceeded.n";
break;
Remember, keep your coding and design simple. Complexity injects more defects.
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Why are you using both
std::string
andchar
arrays?– Thomas Matthews
Sep 2 at 20:46