Read/Write a file in c++ - c++

I'm trying to have this program append a text file, making it a new line with every iteration.
It will append every time, but not add new lines for each new line.
Afterwords, I am trying to have it read out every line in the text file, though it will not read anything but the first word, and display that.
That's what I've done so far:
#include<iostream>
#include<string>
#include<fstream>
#include<ios>
using namespace std;
/*
Return types: void
Types: 1 string, 1 int
Purpose: write to the highscores.txt
*/
void Write_Score(string name, int score);
/*
Return type: Void
Types: N/A
Purpose: Read the highscores.txt
*/
void Read_Score();
int main()
{
string usr_name;
int usr_score = 0;
cout << "Enter your name: ";
cin >> usr_name;
cout << endl;
cout << "Enter your score: ";
cin >> usr_score;
cout << endl;
Write_Score(usr_name, usr_score);
cout << endl << endl << endl;
Read_Score();
}
void Write_Score(string name, int score)
{
ofstream outfile;
outfile.open("Highscores.txt", ios::app);
outfile << name << "\t" << score;
outfile.close();
}
void Read_Score()
{
string name;
int score = 0;
ifstream infile;
infile.open("Highscores.txt", ios::in);
infile >> name >> score;
cout << name << "\t" << score << endl;
infile.close();
}

You need to specify that you want a new line to be appended:
void Write_Score(string name, int score)
{
ofstream outfile;
outfile.open("Highscores.txt", ios::app);
outfile << name << "\t" << score << std::endl;
outfile.close();
}
To read a whole line you can use getline (http://www.cplusplus.com/reference/string/string/getline/).
And to read the whole file you need to loop until you reach the end of the filestream.
Read file line by line this thread will help you with that.

Related

How do I extract specific words from a string in a text file? c++

my assignment is to take a string from a text file and count the number of words in it. I've gotten that far but now we have to be able to take a certain number and display that number word to the console. Say my string is "Hello World" if I enter '2' it should give me the result "World". I'm not really sure how my function should look for this. This is my code so far.
void getFileInfo(ifstream &inFile);
string words(ifstream &inFile);
int numOfWords(ifstream& inFile);
int main() {
ifstream inFile;
string sentence, fileName;
int numCount, word;
getFileInfo(inFile);
numCount = numOfWords(inFile);
inFile.clear(); // resets file pointer from the beginning
inFile.seekg( 0 );
sentence = words(inFile);
cout << sentence << ": has " << numCount << " words in it" << endl;
cout << "Enter a number to extract a word: ";
cin >> word;
}
void getFileInfo(ifstream &inFile){
string fileName;
do{
cout << "Please enter the filename: " << endl;
cin >> fileName;
inFile.open(fileName.c_str());
if(!inFile){
cout << "Invalid try again" << endl;
}
}while(!inFile);
}
string words(ifstream &inFile){
string words, theWords;
getline(inFile, words);
cout << words;
return theWords;
}
int numOfWords(ifstream& inFile){
string fileName, words, str;
int numCount =0;
while(inFile >> words){
++numCount;
}
return numCount;
}
Any suggestions?
Thanks in advance
I would suggest slightly different code for your task. First, write some simple helper functions:
// Clear error flags (EOF, for example) and reset stream to the beginning.
void resetStream(ifstream& stream) {
stream.clear();
stream.seekg(0, ios_base::beg);
}
// Count the words in text file stream.
int getWordsCount(ifstream& stream) {
int count = 0;
while (stream) {
string tmp;
stream >> tmp;
if (!tmp.empty()) ++count;
}
resetStream(stream);
return count;
}
// Read word by specific number.
string getWordByNumber(int number, ifstream& stream) {
string word;
while (number--)
stream >> word;
resetStream(stream);
return word;
}
Now you can easily get the number of words in a file and display a specific word by its number. For example:
int main() {
string fileName;
cout << "Enter the file name: \n";
cin >> fileName;
ifstream stream(fileName);
if (!stream)
cout << "Failed to open file!" << endl;
else {
int totalCount = getWordsCount(stream);
int currentCount = 0;
cout << "Total words count: " << totalCount << "\n\n";
do {
cout << "Enter the word number (enter '0' to finish): ";
cin >> currentCount;
if (currentCount == 0) break;
else if (currentCount > totalCount)
cout << "Invalid value!\n";
else {
string wordByNumber = getWordByNumber(currentCount, stream);
cout << "Word by number: " << "'" << wordByNumber << "'\n";
}
cout << "\n";
}
while (true);
}
return 0;
}
Warning: This code is not very efficient and I have not tested it much. If you have any problems, be sure to write a comment.

c++ how to display the string searching key word with its exact line number?

I have a programmer for c++ that ask me a file name first, then ask for the search word. the line that contains it should be displayed with its exact line number in front.
for example:
20:XXXXXX.
I have code here. I don't know how to display the line number. please help me.
#include <iostream>
#include <string> //to work with strings
#include <fstream>
using namespace std;
int main()
{
int occurenceNumber = 0;
int counter = 0;
int lineNum;
string fileName;
string toSearch;
string lineRead;
ifstream inputFile;
cout << "Enter the file name: ";
cin >> fileName;
inputFile.open(fileName);
if(!inputFile){
cout << "Error opening file, or file doesn't exist!";
cout << "Try again!\n";
return 0;
}
cout << "Enter string to search for: ";
cin >> toSearch;
cin.ignore();
while(getline(inputFile, lineRead))
{
if(lineRead.find(toSearch, 0) < lineRead.length())
{
occurenceNumber++;
cout << lineRead << endl;
}
}
cout << toSearch << " was found " << occurenceNumber;
cout << " times. \n";
inputFile.close();
return 0;
}
You set a counter variable. You just forgot to use it. This is the while loop in your code with that counter variable that you defined but forgot to use.
If you place the counter++ at the beginning of that while loop, the first line is line 1. On the other hand, if you place it at the end of the loop, the first line is line 0.
while(getline(inputFile, lineRead))
{
counter++;
if(lineRead.find(toSearch, 0) < lineRead.length())
{
occurenceNumber++;
cout << counter << ":" << lineRead << endl;
}
}

Reading form a file only displays the last inputted string, creates the file but it is empty

My program creates a file and names it after user input, after that it will continue to loop to and ask if you want to keep adding to the file created. after you say no, then it will close the file and read the first three lines of the file created. My program does not output anything into the file, it appears empty and does read three lines but they are the last user inputted line but three times. How to fix this? Here is my code.
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
//Global Variables
fstream File;
string fileName, writeToFile;
char choice;
void write();
void read();
void exitprogram();
int main()
{
// Name and open the output file
cout << "What is the file name that you want to create?" << endl;
cin >> fileName;
cout << "File " << fileName << " has been created!" << endl;
ofstream File(fileName.c_str());
File.open(fileName.c_str());
if (File.is_open())
{
cout << "File opened successfully." << endl;
write();
}
else
{
cout << "Unable to open file" << endl;
}
return 0;
}
void write()
{
choice = ' ';
cout << "What do you want to add?: " << endl;
getline(cin.ignore(),writeToFile);
File << writeToFile << endl;
cout << "Do you want to add something else to the file (1=YES or 2=NO): ";
cin >> choice;
switch(choice)
{
case '1' :
write();
break;
case '2' :
cout << "Saving..." << endl;
File.close();
read();
break;
}
}
void read()
{
cout <<"Here are the first there lines of file " << fileName << endl;
for (int counter = 1; counter <= 3; counter++)
{
File >> writeToFile;
cout << writeToFile << endl;
}
exitprogram();
}
void exitprogram()
{
exit(0);
}
You shadowed the global File used by write by declaring another in main. (The moral is not to use global variables—pretty much never. Pass parameters instead, although most of yours can just be made local anyway.)

How to open and close a file from a while

I need this program to show the count of words from a file (text document). However, not reseting counter of words. its supposed to be 7 but it is displaying 62 words. I was told to close the file from the second last while and create a new while (which is the last one) and open the file again. I've working on this for a while. However, after making the changes it doesn't display the file anymore. the only thing display in the screen it s a th and account of 2 words.
Thanks for your help
#include<iostream>
#include<fstream>//step#1
#include<string>
using namespace std;
int main()
{
string word,fileName;
char character;
int charcounter = 0, wordcounter = 0;
ifstream inData;// incoming file stream variable
cout << " Enter filename or type quit to exit: ";
cin >> fileName;
//loop to allow for multiple files data reads
while (fileName != "quit")
{
inData.open(fileName.c_str());//open file and bind file to ifstream variable
//loop for file not found validation
while (!inData)//filestream is in fail state due to no file
{
inData.clear();//clear the fail state
cout <<"File not found. Enter the correct filename: ";
cin >> fileName;
inData.open(fileName.c_str());
}
inData >> character;//extract a single character from the file
cout << "\n*****************************\n";
while (inData)
{
cout << character;
inData.get(character);
charcounter++;
}
cout << "\n******************************\n";
cout << fileName << " has " << charcounter << " words." << endl;
inData.close();//close the ifstream conection to the data file
while (inData)
{
cout << word;
wordcounter++;
inData.open(fileName.c_str());
}
charcounter = 0; //reset character count
wordcounter = 0;
//port for next file or exit
cout << "Enter a filename or type quit to exit: ";
cin >> fileName;
}
return 0;
}
Do you want this?
#include<iostream>
#include<fstream>//step#1
#include<string>
using namespace std;
int main() {
string word,fileName;
char character;
int charcounter = 0, wordcounter = 0;
ifstream inData;// incoming file stream variable
cout << " Enter filename or type quit to exit: ";
cin >> fileName;
//loop to allow for multiple files data reads
while (fileName != "quit")
{
inData.open(fileName.c_str());//open file and bind file to ifstream variable
//loop for file not found validation
while (!inData)//filestream is in fail state due to no file
{
inData.clear();//clear the fail state
cout <<"File not found. Enter the correct filename: ";
cin >> fileName;
inData.open(fileName.c_str());
}
cout << "\n*****************************\n";
while (inData)
{
inData >> character;//extract a single character from the file
cout << character;
charcounter++;
}
cout << "\n******************************\n";
cout << fileName << " has " << charcounter << " chars." << endl;
inData.close();//close the ifstream conection to the data file
inData.open(fileName.c_str());
while (inData)
{
inData >> word;
cout << word;
wordcounter++;
}
cout << "\n******************************\n";
cout << fileName << " has " << wordcounter << " words." << endl;
inData.close();//close the ifstream conection to the data file
charcounter = 0; //reset character count
wordcounter = 0;
//port for next file or exit
cout << "Enter a filename or type quit to exit: ";
cin >> fileName;
}
return 0;
}

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