Im having an issue with the last section of coding on here. The // Copy files from infile to outfile. The program transfers my infile which is simply a an 8 digit number , 20392207,splits it up into individual digits using the .at method; and is supposed to save that output to an outfile. I cant figure out how to save the output to the outfile. Any advice?
infile looks as follows
20392207
program output looks like this
The input number :20392207
The number 1:2
The number 2:0
The number 3:3
The number 4:9
The number 5:2
The number 6:2
The number 7:0
The number 8:7
outfile is supposed to look like the program out put, but instead just looks like an exact copy of the infile.
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
int main()
{
string ifilename, ofilename, line, line2;
ifstream inFile, checkOutFile;
ofstream outFile;
char response;
int i;
// Input file
cout << "Please enter the name of the file you wish to open : ";
cin >> ifilename;
inFile.open(ifilename.c_str());
if (inFile.fail())
{
cout << "The file " << ifilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Output file
cout << "Please enter the name of the file you wish to write : ";
cin >> ofilename;
checkOutFile.open(ofilename.c_str());
if (!checkOutFile.fail())
{
cout << "A file " << ofilename << " exists.\nDo you want to continue and overwrite it? (y/n) : ";
cin >> response;
if (tolower(response) == 'n')
{
cout << "The existing file will not be overwritten. " << endl;
exit(1);
}
}
outFile.open(ofilename.c_str());
if (outFile.fail())
{
cout << "The file " << ofilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Copy file contents from inFile to outFile
while (getline(inFile, line))
{
cout << "The input number :" << line << endl;
for (i = 0; i < 8; i++)
{
cout << "The number " << i + 1 << ":";
cout << line.at(i);
cout << endl;
}
outFile << line << endl;
}
// Close files
inFile.close();
outFile.close();
} // main
Here we can see that outFile is only written to outside of the while loop:
while (getline(inFile, line))
{
cout << "The input number :" << line << endl;
for (i = 0; i < 8; i++)
{
cout << "The number " << i + 1 << ":";
cout << line.at(i);
cout << endl;
}
}
outFile << line << endl;
It has no chance of containing the same output as the console
Solution: Write inside the loop the same stuff that was written to the console:
while (getline(inFile, line))
{
cout << "The input number :" << line << endl;
outFile << "The input number :" << line << endl;
blah blah blah
}
But this looks like crap and a function makes like a better solution by eliminating duplication and upping re-usability.
void output(std::ostream & out,
const std::string & line)
{
out << "The input number :" << line << endl;
for (int i = 0; i < 8; i++)
{
out << "The number " << i + 1 << ":";
out << line.at(i);
out << endl;
}
}
and called:
while (getline(inFile, line))
{
output(cout, line);
output(outFile, line);
}
You need to write to outFile inside the while(getline(inFile, line)) loop.
[edit] see user4581301's answer for a more thorough treatment.
Related
I'm trying to read in the database down below into a vector of strings while removing the header lines (lines with >db) and imputing each sequence below it into a string.
This is the code I have right now:
void read_in_database_file(string db_file) {
ifstream fin;
fin.open(db_file);
if (!fin.is_open())
{//if
cerr << "Error did not open file" << endl;
exit(1);
}//if
vector<string> database;
string line = "";
while(getline(fin, line, '>'))
{
database.push_back(line);
}
finding_kmers(database);
}
int main() {
cout << "\n" << endl;
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
cout << "------------------------------------ BLAST -----------------------------------" << endl;
cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
cout << endl;
cout << "Welcome to BLAST" << endl;
cout << "Please enter the name of your datafile" << endl;
string db_file = "";
getline(cin, db_file);
cout << endl;
read_in_database_file(db_file);
}
Currently, all it does is simply remove the ">" but print that line and everything else as is. How do i solve this?
database file:
>db_1
GATCTTGCATTTAGAAAATCATAAGAAATTTACTAAAAAGTATTAGGACTCATGAACAAATTTAAGAATG
TAACACTATATAAGATTGGTATACAAAAATAACTGTACTTCTTCACCAAGAAATCAAGAATCCAAAAATG
>db_2
TAGTTTGTTCTAGGATTTATGTGTTTCCTTAAAGTCTTAGTTTGATTATGTTACATTTAGCATGAGTGAC
TCCATTTTGGTTTGGTTTGGTCTGTTGGGACCTATTGCATGAGTTTAGTTCAAAACAATGGCCTCCCATA
>db_3
TTGTCCTTGCGATAGTTTACTGAGAATGATGATTTCCAATTTCATCCATATCCCTACAAAGGACATGAAC
TCATCATTTTTTATGGCTGCATAGTATTCCATGGTGTATATGTGCCATAATTTCTCAATCCAGTCTATCG
I got these questions that I stuck for the past week, "tag always starts with '<' and ends with '>'link always starts with "<a" or "<A" and ends with '>'comment always starts with "<!--" and ends with "- ->",
How can I count these using only while loop or other loops? I'm in the intro programming class, anything beyond loop, if and switch statement is not allowed to use.
Here is the program I done so far and I can't count the the lines and links at the same time, but if I break them apart, I can get the result I want.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inFile;
char ch,
prevchar,
currchar;
int linenum = 0,
tagnum = 0,
commentnum = 0,
linknum = 0,
cfilenum = 0,
ctagnum = 0;
double percent;
string line;
string filename;
cout << "========================================\n";
cout << " HTML File Analyzer\n";
cout << "========================================\n\n";
cout << "Please enter the the file name(no blank): \n";
cin >> filename;
inFile.open(filename.c_str());
while (!inFile)
{
cout << "Please re-enter the file name:\n";
cin >> filename;
inFile.open(filename.c_str());
}
cout << "========================================\n";
cout << " Text of the file \n";
cout << "========================================\n\n";
while (inFile)
{
for (linenum = 0; getline(inFile, line); linenum++);
}
inFile.get(prevchar);
inFile.get(currchar);
while (inFile)
{
if ((prevchar == '<') && (currchar == 'a'))
linknum++;
prevchar = currchar;
inFile.get(currchar);
}
cout << "========================================\n";
cout << " End of the text \n";
cout << "========================================\n\n";
cout << "Analysis of file\n";
cout << "----------------\n\n";
cout << "Number of lines: " << linenum << endl;
cout << "Number of tags: " << tagnum << endl;
cout << "Number of comments: " << commentnum << endl;
cout << "Number of links: " << linknum << endl;
cout << "Number of chars in file: " << cfilenum << endl;
cout << "Number of chars in tags: " << ctagnum << endl;
cout << "Percentage of characters in tags: " << percent << endl;
return 0;
}
After the first loop has finished, your inFile stream is pointing to the end of the file and its eof flag is set.
Issue these statements inbetween your loops to resp. clear the flag and go back to the start of the file:
inFile.clear();
inFile.seekg(0);
That the first statement is not necessary in C++11, but I don't know what environment you are using. Also note that you can do some of the counting operations together in a loop.
I need to create a program that has 4 columns of words from an input file.
then randomly selects a word from each column and generates a sentence. The ultimate goal is to have a conversation that gets saved to the output file.
I've already created the code that reads the input file, and opens the output file to write on but i'm not sure how to select a word from a column and create the sentence, i'm guessing using an array would work but i'm not certain how to connect it with the file?
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
using namespace std;
int main()
{
string ifilename, ofilename, line;
ifstream inFile, checkOutFile;
ofstream outFile;
char response;
// Input file
cout << "Please enter the name of the file you wish to open : ";
cin >> ifilename;
inFile.open(ifilename.c_str());
if (inFile.fail())
{
cout << "The file " << ifilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Output file
cout << "Please enter the name of the file you wish to write : ";
cin >> ofilename;
checkOutFile.open(ofilename.c_str());
if (!checkOutFile.fail())
{
cout << "A file " << ofilename << " exists.\nDo you want to continue and overwrite it? (y/n) : ";
cin >> response;
if (tolower(response) == 'n')
{
cout << "The existing file will not be overwritten. " << endl;
exit(1);
}
}
outFile.open(ofilename.c_str());
if (outFile.fail())
{
cout << "The file " << ofilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Copy file contents from inFile to outFile
cout << "Hi, what's up? " << endl; // Pre-set opener
while (getline(inFile, line))
{
cout << line << endl;
outFile << line << endl;
}
// Close files
inFile.close();
outFile.close();
} // main
You can use a 2D vector of strings to store the words of the sentences and use a random number generator like rand to pick a particular row element from every column. Something like the following
vector<vector<string>> myConversationVector;
while (choice != "no")
{
std::cout << myConversationVector[rand() % 5][0] <<" "
<< myConversationVector[rand() % 5][1] <<" "
<< myConversationVector[rand() % 5][2] <<" "
<< myConversationVector[rand() % 5][3];
}
having a difficult time finding a way to assign each line of the text file being read to a different variable, i commented above the variables displaying how a line from the text file displaying that variable would look. I want to know what way i can use a forloop to be able to iterate through the entire text file and store data to each of the variables I commented above based on the type of data it needs to store. The three sets of variables all have to be stored by species and in a way they can be manipulated. How can i split up a vector into a set of three variables?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string getInputFileName()
//retrieves the inputfile
{
string fileName;
ifstream inputfile;
//prompting user for filename to be opened
cout << "Enter the file name to be opened: ";
cin >> fileName;
//opening the file for input
inputfile.open(fileName, ios::in);
//checks to see if writing the input file failed
if (inputfile.fail())
{
cout << "Opening file..." << fileName;
cout << "\n";
cout << "The " << fileName << "could not be opened! \n";
cout << "1. Check if file exists. \n";
cout << "2. Check file path. \n;";
}
else
{
cout << "File: " << fileName << " was successfully opened!" << endl;
return fileName;
}
}
string getOutputFileName()
//retrieves the inputfile
{
string fileName;
ofstream outputfile;
//prompting user for filename to be opened
cout << "Enter the file name to be opened: ";
cin >> fileName;
//opening the file for input
outputfile.open(fileName, ios::in);
//checks to see if writing the input file failed
if (outputfile.fail())
{
cout << "Opening file..." << fileName;
cout << "\n";
cout << "The " << fileName << "could not be opened! \n";
cout << "1. Check if file exists. \n";
cout << "2. Check file path. \n;";
}
else
{
cout << "File: " << fileName << " was successfully opened!" << endl;
return fileName;
}
}
int main()
{
//opens clasfication file
ifstream inputFile(getInputFileName());
//declaring year and numberOfSpecies
int year, numberOfSpecies;
string line;
if (inputFile.is_open())
{
//year of file
inputFile >> year;
//echo for year
cout << year << endl;
//number of species of file
inputFile >> numberOfSpecies;
//echo for number of species
cout << numberOfSpecies << endl;
string line;
//variables i need to assign line by line and be able to manipulate
//region of species would look like this in text file: 84
//nameOfspecies would like like this in the text file: Spotted Gecko
//regionSightings would look like this in the text file: 84 95 30 25
vector<string> linesOfData;
for (int i = 0; (!inputFile.eof()) || (i <= numberOfSpecies) ; i++)
{
getline(inputFile, line, '\n');
linesOfData.push_back(line);
//echo vector!
cout << linesOfData[i] << "\n";
}
ofstream outputFile(getOutputFileName());
}
return 0;
}
Pseudo code for your requirements. You will have to fill in the code and do the required testing.
I have used similar logic many times for my requirements. I see this to be more maintainable and scalable.
class spotted_species{
private:
int first_val[];
string species_name;
int locations[];
// Private methods
private:
void assign_species_firstVal (String first_line){
Assign the first line after performing required transformations;
}
int assign_species_name (String Second_Line){
if (the species name exists in predefined array or file) {
assign the name;
}
else {
return -1; // to ignore all 3 lines.
}
}
void assign_species_locations (String third_line){
tokenize by space
convert each token to int and assign. hardly 2 lines code.
}
// Public methods
public:
void show_species(){
std::cout<< "First val";
std::cout<< "Species name";
std::cout<< "Spotted locations";
}
int init(String firstline, String secondline, String ThirdLine){
assign_species_firstVal(firstline);
int status = assign_species_name (secondline);
if (status) {
assign_species_locations (ThirdLine);
}
return status_accordingly;
}
}
int main(int argc, char *argv[])
{
// Create an array of spotted_species to ensure you can hold the required number of
// species from the file.
run a OS command "WC -l" which gives the total number of line in your file.
All file handling could be done here based on the output of the above command.
// Calculate the number of objects you would need based on the number of lines.
// Rough estimate would be fine for these requirements.
int num_species = lines_in_file/3 + 10; // +10 is used to be on safer side.
// Create the objects
spotted_species species_spotted_in_africa[num_species];
int ctr;
while (read file until the last line)
// Read 3 lines at a go,
// store them in 3 variables.
// call init with all 3 arguments.
}
// Now you have all the species information in seperate objects.
// you can access them in a loop or by any other means.
// If you need to perform any additional processing on these objects,
// you always can extend this class or
// you could write another class which can process this class data.
// Flexible, simple, Maintainable and scalable.
return 0;
}
You will have to make some changes as per your exact requirements. I hope this helps.
Based on the fact that you have 3 lines of data per species, eg:
84
Spotted Gecko
84 95 30 25
I would suggest using a vector of struct values instead of string values, where each struct holds the data for a single species. While looping through the input file, read 3 lines at a time, parse them into an instance of the struct, and then push it into* the vector.
Try this:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
struct species
{
int region;
string name;
std::vector<int> regionSightings;
};
bool openInputFile(ifstream &inputfile)
{
string fileName;
//prompting user for filename to be opened
cout << "Enter the input file to be opened: ";
getline(cin, filename);
//opening the file for input
cout << "Opening file: " << filename << endl;
inputfile.open(fileName);
//checks to see if opening the input file failed
if (!inputfile)
{
cout << "File: " << fileName << " could not be opened!" << endl;
cout << "1. Check if file exists." << endl;
cout << "2. Check file path." << endl;
return false;
}
cout << "File: " << fileName << " was successfully opened!" << endl;
return true;
}
bool openOutputFile(ofstream &outputfile)
{
string fileName;
//prompting user for filename to be opened
cout << "Enter the output file to be opened: ";
getline(cin, filename);
//opening the file for input
cout << "Opening file: " << fileName << endl;
outputfile.open(fileName);
//checks to see if opening the output file failed
if (!outputfile)
{
cout << "File: " << fileName << " could not be opened!" << endl;
cout << "1. Check if file exists." << endl;
cout << "2. Check file path." << endl;
return false;
}
cout << "File: " << fileName << " was successfully opened!" << endl;
return true;
}
int main()
{
//opens clasfication file
ifstream inputFile;
if (openInputFile(inputFile))
{
//declaring year and numberOfSpecies
int year, numberOfSpecies;
string line;
//year of file
inputFile >> year;
//echo for year
cout << "Year: " << year << endl;
//number of species in file
inputFile >> numberOfSpecies;
//echo for number of species
cout << "# species: " << numberOfSpecies << endl;
//there are three lines per species
//region of species, eg: 84
//nameOfspecies, eg: Spotted Gecko
//regionSightings, eg: 84 95 30 25
vector<species> speciesData;
for (int i = 0; i < numberOfSpecies; ++i)
{
species s;
if (!getline(inputFile, line))
{
cout << "File: " << fileName << " could not read a species region!" << endl;
break;
}
if (!(istringstream(line) >> s.region))
{
cout << "File: " << fileName << " could not parse a species region!" << endl;
break;
}
if (!getline(inputFile, s.name))
{
cout << "File: " << fileName << " could not read a species name!" << endl;
break;
}
if (!getline(inputFile, line))
{
cout << "File: " << fileName << " could not read a species sightings!" << endl;
break;
}
istringstream iss(line);
int num;
while (iss >> num)
s.regionSightings.push_back(num);
if (!iss.eof())
{
cout << "File: " << fileName << " could not parse a species sightings!" << endl;
break;
}
speciesData.push_back(s);
//echo vector!
cout << s.region << " " << s.name << " " << line << endl;
}
cout << "Closing input file" << endl;
inputFile.close();
ofstream outputFile;
if (openOutputFile(outputFile))
{
for (std::vector<species>::iterator iter = speciesData.begin();
iter != speciesData.end();
++iter)
{
species &s = *iter;
// write species data to outputFile as needed...
}
cout << "Closing output file" << endl;
}
cout << "Finished" << endl;
}
return 0;
}
I am writing a program that is going to have to import data from a file into various containers. I have it importing everything properly, but it is continuing to read after what is supposed to be the eof. I have a feeling I am not properly telling the loop when to end, but the code is below for everyone to look at.
bool InitLoad(vector<string>&num, vector<string>&name, vector<double>&price, vector<char>&tax)
{
ifstream invFile;
int intTemp;
string strTemp;
double dubTemp;
char chTemp;
string fileLoc = "C:/Users/owner/Documents/Visual Studio 2010/Projects/CISS 350/Week 1 Grocery Register/Week 1 Grocery Register/Invent.dat";
//Open Invent.dat file. Location below is the location used on creators computer. Other may need to modify file location
invFile.open(fileLoc.c_str(), ios::in);
//If Invent.dat file fails to open display error message and return false
if(invFile.fail())
{
cout << "Could not open inventory file" << endl;
return false;
}
if(invFile)
{
//Read first line of the file
getline(invFile, strTemp, ' ');
while(invFile) //while invFile contains data display import the list
{
cout << strTemp << " ";
num.push_back(strTemp);
getline(invFile, strTemp, ' ');
cout << strTemp << " ";
name.push_back(strTemp);
getline(invFile, strTemp, ' ');
dubTemp = atof(strTemp.c_str());
cout << dubTemp << " ";
price.push_back(dubTemp);
invFile.get(chTemp);
cout << chTemp;
tax.push_back(chTemp);
getline(invFile, strTemp, ' ');
}
}
invFile.close();
cout << endl;
//Verify Proper input...REMOVE WHEN COMPLETE
cout << "Verifying input data correct..." << endl;
int vecSize = num.size();
cout << vecSize << endl;
for(int i = 0; i < vecSize; i++)
{
cout << num[i] << " " << name[i] << " " << price[i] << " " << tax[i] << endl;
}
}
Your check does not check eof flag
http://www.cplusplus.com/reference/ios/ios/operator_bool/
use invFile.eof() instead
And also eof flag would be setted after reading past EOF
PS: OMG!! do not use atof, just do invFile << dubTemp
Since your data is space separated you can uses formatted input instead of getline() on every string.
Something along the lines of this.
string lineTemp;
while(getline(invFile, lineTemp)) //while invFile contains data display import the list
{
string strTemp1, strTemp1, dubTemp, chTemp;
istringstream lstr(lineTemp);
if(lstr >> strTemp1 >> strTemp2 >> dubTemp >> chTemp) {
num.push_back(strTemp1);
name.push_back(strTemp2);
price.push_back(dubTemp);
tax.push_back(chTemp);
cout << strTemp1 << " "
<< strTemp2 << " "
<< dubTemp << " "
<< chTemp << endl;
}
else {
// Something is wrong with the line format.
}
}
This will read the data in a formated way and to the proper type. Plus you don't have to worry about empty lines or extra characters in lines.