Using fstream in VIsual C++ - c++

I am trying to use fstream but am running into problems when trying to open a file from within Visual Studio 2013. In Visual Studio, I have two resources that I have enabled to be used in the project titeld input1.txt and input2.txt . If I directly run the application from the Debug folder using File Explorer, I am able to use the ifles. If I try to run it from within Visual Studio with ctrl, neither files can be found. I believe my code is correct, but I'm not sure what changes to make to the project to have it run correctly.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const bool VERBOSE(true);
int main(){
ifstream input;
ofstream output;
string inFileName;
string outFileName;
string tempString;
// Get input file name into a string
cout << "Input file name: " << flush;
cin >> inFileName;
if (VERBOSE)
{
cout << "Input file name is " << inFileName << endl;
}
// Convert filenames to C strings and use stream.open()
input.open(inFileName.c_str());
if (input.fail())
{
cout << "File " << inFileName << " cannot be opened" << endl;
return -1;
}
// Get output file name into a string
cout << "Output file name: " << flush;
cin >> outFileName;
if (VERBOSE)
{
cout << "Output file name is " << outFileName << endl;
}
// Convert filenames to C strings and use stream.open()
// When opening output file, it will create the file if it
// does not exist, and will clobber it if it does.
output.open(outFileName.c_str());
if (output.fail())
{
cout << "File " << outFileName << " cannot be opened" << endl;
return -2;
}
// While there is more to the input file, get a word
// and copy it to the output file on its own line.
while (!input.eof())
{
input >> tempString;
if (VERBOSE)
{
cout << " Length is " << tempString.length() << " for " << flush;
}
if (tempString.length() > 0)
{
if (VERBOSE)
{
cout << tempString << endl;
}
output << tempString << endl;
}
else
{
if (VERBOSE)
{
cout << "No more input" << endl;
}
}
// This is needed to keep the last non-whitespace word
// read in from being printed twice if the file ends in
// whitespace, including a newline.
tempString.clear();
}
cout << endl;
return 0;
}

Specify the full path to the files when you cin them.

Related

How to remove certain lines when reading FASTA files?

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

How to get input file to go into an array

I'm trying to get information from an input file into an output file, which I have done, but I can't figure out how to get the numbers from the file into an array and only output the numbers divisible by 7. I've been stuck for a few hours, please help.
#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
char array[10];
int numberz = 0;
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))
{
fscanf(ifilename, &array[numberz]);
cout << line << endl;
outFile << line << endl;
}
// Close files
inFile.close();
outFile.close();
} // main
I'd use boost::filesystem for that task.
#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
namespace fs = boost::filesystem;
int main()
{
fs::path ifilename;
std::cout << "Input file: ";
std::cin >> ifilename;
fs::ifstream inFile{ifilename};
if ( inFile.fail() )
throw std::invalid_argument("Could not open file");
fs::path ofilename;
std::cout << "Output file: ";
std::cin >> ofilename;
if ( fs::exists(ofilename) )
{
std::cout << ofilename << " exists. Do you want to overwrite it? (y/n) ";
char response;
std::cin >> response;
if ( ! ( response == 'y' || response == 'Y' ) )
return 1;
}
fs::ofstream outFile{ofilename};
if ( outFile.fail() )
throw std::invalid_argument("Could not open file");
std::vector<std::string> array;
std::string line;
while ( std::getline(inFile, line) )
{
array.push_back( line );
std::cout << line << '\n';
outFile << line << '\n';
}
inFile.close();
outFile.close();
}

Issue with saving an edited infile to an outfile in c++

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.

Selecting random words from an generating a sentence from an input file

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];
}

Iterating through a text file and assigning variables for each line

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;
}