incorrect stof() declaration - c++

I'm reading in values from a text file and printing the to screen as strings. The idea is to read in each individual string and print them to screen along with the running average of strings read in printed next to it.
i have this for my string to float declaration
int main()
{
string inputfile, intstring;
float counter;
counter = 0;
float average;
average = 0;
float stringconv = stof(intstring);
cout << "Enter the name of a file to open\n";
cin >> inputfile;
ifstream inFile;
inFile.open(inputfile.c_str());
and later on to calculate the average
while (!inFile.eof())
{
getline(inFile, intstring, ' ');
cout << intstring <<","<<average<< endl;
//increments counter to keep average output correct
counter = counter +1;
//goes to next line at each space encountered in text file
average = (counter + stringconv) /2;
}
I've included this just in case my issue lies there. Can anyone tell me how to properly declare my conversion?
and here is a full version which compiles
#include <math.h>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string inputfile, intstring;
float counter;
counter = 0;
float average;
average = 0;
float dividor;
dividor = 1;
cout << "Enter the name of a file to open\n";
cin >> inputfile;
ifstream inFile;
inFile.open(inputfile.c_str());
if (!inFile)
{
cout << "Error opening file " << inputfile << endl;
char stopchar;
cin >> stopchar;
return -1;
}
while (!inFile.eof())
{
//goes to next line at each space encountered in text file
getline(inFile, intstring, ' ');
cout << intstring <<","<<average<< endl;
float stringconv;
stringconv = stof(intstring);
average = (counter + stringconv)/dividor ;
dividor = dividor +1;
//increments counter to keep average output correct
}
inFile.close();
char stopchar;
cin >> stopchar;
}

Here:
string inputfile, intstring;
...
float stringconv = stof(intstring);
You can't do that. I mean, you can, but it doesn't do what you think it does. You think you're creating a macro or function or something, so that you can change intstring and then stringconv will automatically change. But what you're actually doing is converting the uninitialized string into an integer once, and never changing it again. You must do the conversion inside the read loop.
EDIT: If you're not required to use stof(), then you can save yourself a lot of headaches by using the stream input operator:
float number;
inFile >> number; // this is the basic form
while(inFile >> number) // this is how to do it as a loop
...

In C++, float stringconv = stof(intstring); won't meen automatic conversion like assign in Verilog.
Call stof() each time you need to convert.
Try this:
while (!inFile.eof())
{
getline(inFile, intstring, ' ');
cout << intstring <<","<<average<< endl;
//increments counter to keep average output correct
counter = counter +1;
//goes to next line at each space encountered in text file
stringconv = stof(intstring); // add this here
average = (counter + stringconv) /2;
}

Related

Reading coordinate file with ifstream while ignoring headers and writing to array

There's a series of coordinates I'm trying to write to an array so I can perform calculations on, but I haven't been able to read the file correctly since I can't ignore the headers, and when I do remove the headers it also doesn't seem to correctly write the values to the array.
The coordinate file is a txt as below.
Coordinates of 4 points
x y z
-0.06325 0.0359793 0.0420873
-0.06275 0.0360343 0.0425949
-0.0645 0.0365101 0.0404362
-0.064 0.0366195 0.0414512
Any help with the code is much appreciated. I've tried using .ignore to skip the two header lines but they don't seem to work as expected.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main() {
int i = 1;
int count = 1;
char separator;
const int MAX = 10000;
int x[MAX];
int y[MAX];
int z[MAX];
int dist[MAX];
char in_file[16]; // File name string of 16 characters long
char out_file[16];
ifstream in_stream;
ofstream out_stream;
out_stream << setiosflags(ios::left); // Use IO Manipulators to set output to align left
cout << "This program reads a series of values from a given file, saves them into an array and performs calculations." << endl << endl;
// User data input
cout << "Enter the input in_file name: \n";
cin >> in_file;
cout << endl;
in_stream.open(in_file, ios::_Nocreate);
cout << "Enter the output file name: \n";
cin >> out_file;
cout << endl;
out_stream.open(out_file);
// While loop in case in_file does not exist / cannot be opened
while (in_stream.fail()) {
cout << "Error opening '" << in_file << "'\n";
cout << "Enter the input in_file name: ";
cin >> in_file;
in_stream.clear();
in_stream.open(in_file, ios::_Nocreate);
}
while (in_stream.good) {
in_stream.ignore(256, '\n');
in_stream.ignore(256, '\n');
in_stream >> x[i] >> separator >>y[i] >> separator >> z[i];
i++;
count = count + 1;
}
cout << x[1] << y[1] << z[1];
in_stream.close();
out_stream.close();
return 0;
}
Within your reading of the file, you are using in_stream.ignore(256, '\n'); correctly, but you want to use it outside the while loop. When you have it inside the while loop, every time it runs, you will ignore the first two lines, then read the third. Your output would actually read in only a third of what you expect. To fix this, just move those 2 lines outside the while loop.
in_stream.ignore(256, '\n');
in_stream.ignore(256, '\n');
while (in_stream.good)
{
in_stream >> x[i] >> separator >>y[i] >> separator >> z[i];
i++;
count = count + 1;
}
This should fix your problem, but you should generally use a vector instead of an array. Vectors automatically manage memory and check for bounds instead of you having to do that.
Also, good practice is to read values out of the stream as the while condition instead of in_stream.good:
while(stream >> var)
{
//Your code here
}
Here is a good resource on why that is.

Parse (split) a txt file with a string and int in c++

im a Student and new to this site. I want to split my txt file with my highscore data back to my Highscore List.
The txt file stores my Highscore like name:score
My parsing is not working and i dont know why?
I just want to split it to name and score again and then put it in my HighscoreList.
If you have any question about the code just ask :)
#include "highscore.h"
highscore::highscore(){
}
struct highscore::Player{
string spielerName;
int score;
};
void highscore::writeHighscore(string name, int score ,int playerNumberx){
Player HighscoreListe[100];
for(int i=0;i<=99;i++){
HighscoreListe[i].score = {0};
}
for(int i=0;i<=99;i++){
HighscoreListe[i].spielerName = "leer";
}
HighscoreListe[playerNumberx].spielerName = name;
HighscoreListe[playerNumberx].score = score;
int i, j,temp;
string temp1;
ifstream myfile("scores.txt");
string line;
//heres the point where i need help!!
if (myfile.is_open()){
int z=0;
while(getline(myfile, line)){
string name1;
string score1;
int d = 20;
while(line[z] != ':'){
name1 += line[z];
z++;
}
z = z+2;
while(line[z] != '\0'){
score1 += line[z];
z++;
}
HighscoreListe[d].spielerName = name;
HighscoreListe[d].score = score;
d++;
}
myfile.close();
}else cout << "Unable to open file" << endl;
for(i = 0; i<100; i++) {
for(j = i+1; j<100; j++)
{
if(HighscoreListe[j].score < HighscoreListe[i].score) {
temp = HighscoreListe[i].score;
temp1 = HighscoreListe[i].spielerName;
HighscoreListe[i].score = HighscoreListe[j].score;
HighscoreListe[i].spielerName = HighscoreListe[j].spielerName;
HighscoreListe[j].score = temp;
HighscoreListe[j].spielerName = temp1;
}
}
}
ofstream myfilex("scores.txt");
if (myfilex.is_open()){
for(int i = 99;i>89;i--){
myfilex << HighscoreListe[i].spielerName << ":" << HighscoreListe[i].score<<endl;
}
myfilex.close();
}
else cout << "Unable to open file" << endl;
}
void highscore::readHighscore(){
string line;
ifstream myfile("scores.txt");
if (myfile.is_open()){
while(getline(myfile, line)){
cout << line << endl;
}
}
else cout << "Unable to open file" << endl;
}
Make a >> overload for highscore::Player.
In the >> overload
Use std::getline to read a line from the input stream.
Create a std::istringstream out of the line.
Use std::getline to read up to the : from the istringstream into a local string name;.
Use another std::getline to read the rest of the line into a string.
Convert the string into an int with std::stoi and store into a local int score;. Make sure you provide a pos argument.
Ensure that the entire string was converted by comparting the pos argument with the string's length.
If nothing went wrong, store name and score into the highscore::Player passed by the caller. Otherwise, set the failbit on the input stream with setstate
return the input stream.
Now the reading code should be something simple like
int scorecount = 0;
while (myfile >> HighscoreListe[scorecount])
{
scorecount++;
}

Am I passing parameters correctly?

I'm trying to get the function getFilename to prompt the user for which file to read and then pass that to the function readFile which calculates the numbers in the file and then (using displayAverage) display the average of the numbers in the file.
I'm new to coding and can't figure out why it doesn't seem to be using the readFile function... the program prompts the user for the file but after that it just inputs a blank line. Am I calling the functions & passing the parameters correctly?
void getFilename(char fileName[])
{
cout << "Please enter the filename: ";
cin >> fileName;
return;
}
float readFile(char fileName[])
{
cout.setf(ios::fixed);
cout.precision(0);
ifstream fin(fileName);
int sum = 0;
int numValue = 0;
float grades = 0;
float average= 0;
if (fin.fail())
{
cout << "Error opening file \"" << fileName << "\"";
return false;
}
while (!fin.eof())
{
fin >> grades;
sum += grades;
numValue++;
if (numValue != 10)
cout << "Error reading file \"" << fileName << "\"";
}
fin.close();
average = sum / 10;
return average;
}
void displayAverage(int average)
{
cout << average;
return;
}
int main()
{
char* fileName;
int average;
getFilename(fileName);
readFile(fileName);
displayAverage(average);
return 0;
}
Your program has undefined behaviour since fileName does not point to anything valid that can hold data.
Unless you are required to use an array of chars to hold the filename, use std::string for fileName.
std::string fileName;
If you are required to use an array of chars to hold the filename, use
char fileName[FILENAME_LENGTH];
Make sure FILENAME_LENGTH is large enough for your needs.

Two nearly identical C++ functions being used to accomplish nearly the same task(find the average of lines of 25 numbers), yet only one is functional?

I am writing a program in C++ that is supposed to locate 6 specific lines in an XML file, each of the 6 lines individually holding 25 numeric values, and then find the average of those 25 numeric values for each line separately and output that average to the console window and to an output file. Three of the 6 lines deal with voltage data, and the other three lines deal with Wattage data.
I've been able to find the average of each of the 3 wattage lines. However, I'm having continual issues whenever I try to find the average of each of the 3 voltage lines, despite the function to find the average of each of the 3 voltage lines being very similar to the working function that finds the average of each of the 3 wattage lines, the averages being output just aren't correct for the voltage lines(see screenshots).
Where is the point of fault for void voltAvg(); that is resulting in incorrect output? I've been working on this project for ages and this is the single issue standing between me and a complete project and I've been agonizing over it for hours. Someone please lend me a hand! I would just like to extend a tremendous thank you in advance for taking the time to help me out!
Expected output:http://imgur.com/i6ENvrN
Current Output: http://imgur.com/Unl2aLO
XML file: http://pastebin.com/5hMy9RzK
#include <fstream>
#include <string>
#include <iostream>
#include <regex>
#include <sstream>
void timestamps();
void voltAvg();
void wattAvg();
void electric();
using namespace std;
float sum; //global variable
ifstream infile;
ofstream outFile;
int main() {
outFile.open("Outputdata.txt");
infile.open("Groupproject.xml"); // Opens the XML file containing the information that is to be read
if (infile.fail())
{
cout << "The file is not able to be located" << endl;
system("Pause");
exit(1);
}
electric();
infile.clear();
infile.seekg(0, ios::beg);
timestamps();
infile.clear();
infile.seekg(0, ios::beg);
voltAvg();
infile.clear();
infile.seekg(0, ios::beg);
wattAvg();
infile.close();
outFile.close();
system("pause");
return 0;
}
void electric() {
string fileinput;
regex electric_regex("electric_6[1-6]");
smatch electric_matches;
while (getline(infile, fileinput)) { //Until the end of the file is reached, obtain each line
if (regex_search(fileinput, electric_matches, electric_regex)) { // if regex_search is able to locate a line which has elements matching the regex expression "time_regex" output the located element
cout << electric_matches[0] << endl;
outFile << electric_matches[0] << endl;
}
}
cout << "-------------------------------------------" << endl;
}
void timestamps() {
string fileinput;
regex time_regex("\\d\\d\\d\\d-\\d\\d-\\d\\d\\w\\d\\d:\\d\\d:\\d\\d\\.716Z");
smatch time_matches;
while (getline(infile, fileinput)) { //Until the end of the file is reached, obtain each line
if (regex_search(fileinput, time_matches, time_regex)) { // if regex_search is able to locate a line which has elements matching the regex expression "time_regex" output the located element
cout << time_matches[0] << endl;
outFile << time_matches[0] << endl;
}
}
cout << "-------------------------------------------" << endl;
}
void voltAvg() {
float avevolt;
float dataValuesvolt;
int indexvolt;
string svolt;
string locateWordvolt;
getline(infile, svolt); //gets first line of file
indexvolt = svolt.find(' '); //finds first white space
locateWordvolt = svolt.substr(0, indexvolt); //cuts up line and assigns to locateWord
while (locateWordvolt != "<VoltAmpereReactiveTimeSeries")
{
getline(infile, svolt);
indexvolt = svolt.find(' ');
locateWordvolt = svolt.substr(0, indexvolt);
}
infile.ignore(91, '\n'); // Ignores all of the stuff on the "<VoltAmpereReactiveTimeSeries" line and gets to the numbers on the subsequent line
for (int i = 0; i < 3; i++) {
for (int count = 0; count < 25; count++) //sums 25 voltage/wattage values
{
infile >> dataValuesvolt;//extract voltage data values from InFile
sum += dataValuesvolt;
}
avevolt = sum / 25.0; //calculate the average voltage
cout << "Average Voltage: " << avevolt << endl;//outputs ave on screen
outFile << "Average Voltage: " << avevolt << endl; //Prints the average to out file
sum = 0; // re-initialize sum
getline(infile, svolt); //gets first line of file
indexvolt = svolt.find(' '); //finds first white space
locateWordvolt = svolt.substr(0, indexvolt); //cuts up line and assigns to locateWord
while (locateWordvolt != "<VoltAmpereReactiveTimeSeries")
{
getline(infile, svolt);
indexvolt = svolt.find(' ');
locateWordvolt = svolt.substr(0, indexvolt);
}
}
}
void wattAvg() {
float ave;
float dataValues;
int index;
string s;
string locateWord;
getline(infile, s); //gets first line of file
index = s.find(' '); //finds first white space
locateWord = s.substr(0, index); //cuts up line and assigns to locateWord
while (locateWord != "<WattageTimeSeries")
{
getline(infile, s);
index = s.find(' ');
locateWord = s.substr(0, index);
}
infile.ignore(0, '\n'); // Ignores all of the stuff on the "<WattageTimeSeries" line and gets to the numbers on the subsequent line
for (int i = 0; i < 3; i++) {
for (int count = 0; count < 25; count++) //sums 25 voltage/wattage values
{
infile >> dataValues;//extract wattage data values from InFile
sum += dataValues;
}
ave = sum / 25.0; //calculate the average wattage
cout << "Average Wattage: " << ave << endl;//outputs ave on screen
outFile << "Average Wattage: " << ave << endl; //Prints the average to out file
sum = 0; // re initialize sum
getline(infile, s); //gets first line of file
index = s.find(' '); //finds first white space
locateWord = s.substr(0, index); //cuts up line and assigns to locateWord
while (locateWord != "<WattageTimeSeries")
{
getline(infile, s);
index = s.find(' ');
locateWord = s.substr(0, index);
}
}
}
float sum; //global variable
First, why a global variable? If you need the value outside the function, just return it instead of a void.
Second, sum is never initialised to 0, but then you do a sum += dataValuesvolt;. Whatever was in sum before you add something to it will still be there.
Also, this is outside the scope of this question, but if I were you, I would I have a close look at the structure of your code. For instance, your average functions are doing way too many things at the same time.

How do i print a file in my c++ program with words taken out?

I'm writing a program in c++ and I need to ask the user for a file name, print the file and then reprint it with every 5th word missing. I've gotten as far as to asking them file name, checking for errors and printing out the file, I'm just completely lost on how to reprint it with every 5th word missing, any help?
#include <iostream>
#include <fstream>
#include <cctype>
#include <string>
using namespace std;
int main()
{
const int SIZE = 51;
char fileName[SIZE];
char ch;
ifstream inFile;
bool lastWasLetter = true;
const string UNDERLINE = "__________";
cout << "Please enter a file name: ";
cin >> fileName;
inFile.open (fileName, ios::in);
while (!inFile)
{
cout << fileName << " could not be opened, please enter new file name: ";
cin >> fileName ;
inFile.open (fileName, ios::in);
}
inFile.clear(); // reset read pointer to very beginning of file
inFile.seekg(0L, ios::beg);
std::string word;
int count = 0;
while (inFile >> word)
{
count++;
if (count % 5 != 0)
cout << word << endl;
}
}
And yes this a project I'm working on for my programming class.
Just keep track of the number of words you've read and skip printing every 5th word, i.e. whenever the word count is a multiple of 5. For example:
std::string word;
int count = 0;
while (inFile >> word) {
count++;
if (count % 5 != 0)
cout << word << endl;
}