Min/max Logic and file read error - c++

Reading from file and Min/max logic.
As more info comes in, I will update my question, statements, and code every 30 minutes so I don't edit faster than some can answer.
My question is, how do I set the program to read one name at a time and not concatenate the names?
The file is a .txt file, and reads:
Jackie Sam Tom Bill Mary Paul Zev Barb John
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// File stream objects
ifstream inputFile;
inputFile.open("LineUp.txt");
// Non-user variables
string first_In_Line = "",
last_In_Line = "",
previous_Name = "",
next_name = "";
if (inputFile)
{
// Display message to user
cout << "Reading file... \n";
while (inputFile >> next_name)
{
cout << next_name;
if (next_name > last_In_Line)
{
first_In_Line = last_In_Line;
last_In_Line = next_name;
}
else if (next_name < first_In_Line)
{
last_In_Line = first_In_Line;
first_In_Line = next_name;
}
// This else clause should only apply to the first iteration
else
{
first_In_Line = next_name;
}
}
//Close the file
inputFile.close();
// Display first in line and last in line
cout << first_In_Line << " is first in line." << endl;
cout << "And " << last_In_Line << " is last in line." << endl;
}
else
{
// Display error message.
cout << "Error opening the file.\n";
}
return 0;
}
Output is:
Reading file...
JackieSamTomBillMaryPaulZevBarbJohnJohn is first in line.
And Sam is last in line.

What I am proposing to you is to use array then use the algorithm sort function
Array is a data structure which is use to save data while the program is running.
Therefore we could save those data from the file to that array. the name of the array is dataFromFile that could save up to 9 string values. so if you have more names in your file just update the size of the array or use vector
ifstream file("dataToRead.txt");
string dataFromFile[9];
string line;
int index = 0;
if(!file)
{
cout<<"cannot find this file" <<endl;
}
else
{
if(file.is_open())
{
while (getline(file,line))
{
dataFromFile[index] = line;
index++;
}
file.close();
}
}
Then display what we have inside of the array using a loop
for(int j=0;j<9;j++)
{
// to do display
cout<<dataFromFile[j] <<endl;
}
NOW to sort them just #include <algorithm> then use the sort method on the array which is called dataFromFile
sort(begin(dataFromFile),end(dataFromFile));
Then redisplayed what you have into the array
for(int j= 0 ;j < 9;j++)
{
// after sorting
cout<<dataFromFile[j] <<endl;
}

Without using arrays, which is the best solution, there was a logic error in if-statements.
First, strings were initialized as empty, so empty strings were always sorted as first_In_Line. first_In_Line needed assigned a value on the first iteration of the while-loop.
Next, by the fourth iteration of the while loop, the variables became illogically assigned, and "Sam" was passed back and forth between first_In_Line and last_In_Line through the rest of the while-loop.
Here's how I solved this problem:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// File stream objects
ifstream inputFile;
inputFile.open("LineUp.txt");
// Non-user variables
string first_In_Line = "",
last_In_Line = "",
next_name = "";
if (inputFile)
{
// Display message to user
cout << "Reading file... \n\n";
while (inputFile >> next_name)
{
cout << next_name << endl; // list the names
if (last_In_Line == first_In_Line)
{
first_In_Line = next_name;
}
else if (next_name > last_In_Line)
{
last_In_Line = next_name;
}
else if (next_name < first_In_Line)
{
first_In_Line = next_name;
}
}
//Close the file
inputFile.close();
// Display first in line and last in line
cout << endl << first_In_Line << " is first in line." << endl;
cout << "And " << last_In_Line << " is last in line." << endl;
}
else
{
// Display error message.
cout << "Error opening the file.\n";
}
return 0;
}

Related

Way to deal with multiple user arguments in C++?

Task Commands Picture Ok, I've progressed a bit more from my previous work but I just can't get past this issue which probably isn't that big. My task, which is basically a text file editor, requires multiple user arguments after the program begins running, ranging from let's say 1 such as "details" to 3 or 4 with random user input like display x y or savepart x y (see attached image). My code currently takes in the first line the user inputs using cin and getline but it can only read known strings such as load userinput.txt (which is the filename), and quit and I don't know how I can store the user's entered values for variables. How do I solve this?
What basically needs to probably change is the getline under the while loop or what's written in the if statements but I've tried everything.
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
using namespace std;
string secondword;
string fword;
string line;
ifstream myfile;
fstream fFile;
bool running = true;
int x;
int length;
int main(int argc, char* argv[]) {
while (running) {
getline(cin, fword); //Reads first line user inputs
//if first word equals laod command load file to memory
if (fword == "load userinput.txt") {
ifstream myfile("userinput.txt", ifstream::binary);
myfile.seekg(0, myfile.end); //Searches till end of file
length = myfile.tellg(); //Sets length as total number of chars in file
myfile.seekg(0, myfile.beg); //Searches from the beginning
char* buffer = new char[length]; //Allocates file memory to pointer
cout << "Reading " << length << " characters... " << endl;
myfile.read(buffer,length); //reads file and compares buffer size with legnth size
if (myfile)
cout << "All characters read and stored in memory sucessfully" << endl;
else
cout << "error: only " << myfile.gcount() << " can be read" << endl;;
myfile.close();
}
//Quit
if (fword == "quit") {
running = false; //Breaks while loop statement
cout << "User has quit the program" << endl;
}
//Clear all lines in text
if (fword == "clear all") {
fFile.open("userinput.txt", ios::out | ios::trunc);
fFile.close();
cout << "All lines have been cleared" << endl;
}
//Display All Text
if (fword == "display text") {
myfile.open("userinput.txt", ios::in);
while (getline(myfile, line)) { //read data from file object and put it into string.
cout << line << endl; //print the data of the string
}
}
}
return 0;
}

File reading and Manipulation

I have a text file:
1
2
3
stop
4
The code has to add each number to the previous number to get a new value and it needs to stop when it reads the "stop" in the file.
For example output would be:
1
3
5
Reading has stopped
How can I break the code for my output to be like this?
The "reading has stopped", only has to appear when there is a 'stop' in the file. otherwise the output should just be numbers.
You can read each piece of the file into a string and end if the input is "stop". If the input isn't "stop" you can convert it to an int using std::stoi
#include <string>
#include <iostream>
#include <fstream>
int main() {
std::string numberString;
std::ifstream file{ "filename.txt" };
int previousNumber = 0;
while (file >> numberString)
{
if(numberString == "stop")
{
break;
}
try {
int number = std::stoi(numberString);
std::cout << (number + previousNumber) << " ";
previousNumber = number;
} catch(...) {
std::cout << "invalid number" << std::endl;
}
}
file.close();
std::cout << "Reading has stopped" << std::endl;
}
If your text file has only one string "stop", then there's a very easy solution: you just keep reading integers until the reading fails
int main() {
ifstream ifs("test.txt");
int first = 0;
int second;
while (ifs >> second) {
cout << first + second << ' ';
first = second;
}
cout << "Reading has stopped" << endl;
return 0;
}
The problem with this solution is that if you have other strings in the text file and you want to handle them in a different way, this solution will fail.
Hope it helps.

C++ Searching CSV file from inputted string

I am trying to create a program that will load the CSV file and based upon the inputted word search through the file and return any lines that contain the word. The CSV file is a mass download of tweets and has the following columns:
Date & Time Created
The Tweet
The tweets are also surrounded by b'TWEET TEXT HERE' so would need to remove the b' ' from when it printed out. I am unable to change anything to do with the CSV file sadly so cant manually remove it. The issues I am having are:
Listing the total amount of tweets within the file the program just freezes
Removing the b' ' from the tweets
The else statement causes "not found" to be constantly printed
Code I currently have that is returning the tweets that contain the inputted word but also the false positive.
The current output when running the below code
#include "stdafx.h"
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
string token;
ifstream fin;
fin.open("sampleTweets.csv");
if (fin.is_open())
{
cout << "File opened successfully" << "\n";
}
else {
cout << "Error opening file" << "\n";
}
cout << "Enter search word: ";
cin >> token;
"\n";
string line;
while (getline(fin, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
} else {
cout << token << " not found" << endl;
}
}
fin.close();
char anykey;
cout << "press any key";
cin >> anykey;
return 0;
}
Code I was using for counting total tweets
int count = 0;
char str[140];
while (!fin.eof())
{
fin.getline(str, 140);
count++;
}
cout << "Number of lines in file are " << count;
Any help on this would be amazing as I am quite new to C++ and not sure where to go from here!
You can remove the "b" with erase:
if (line.find(token) != string::npos){
int n= line.find(",");
line.erase(n+1, 3);
cout << line << endl;
}
and you can count the lines inside the while loop:
int count = 0;
while (getline(fin, line)) {
++count;
...
}
EDIT: you can remove the extra quotes and commas like so:
line[n] = ' '; // change comma int space
line.erase(n+1, 4); // remove "b""
line.resize(line.size()-5); // remove trailing """,,

Word Counting Program C++

I'm currently trying to program a word counting program in C++ and am running into difficulties getting it to parse through a string and separate words from one another. In addition to this I am having a hard time getting the word count for unique words to increment each time the word repeats. My findWord() and DistinctWords() functions are most likely the issues from what I can tell. Perhaps you will see something I do not though in the others, as for the aforementioned functions I have no clue as to what's messing up in them. These are the directions provided by my instructor:
Create a program which will count and report on the number of occurrences of distinct, case insensitive words in a text file.
The program should have a loop that:
1.Prompts the user to enter a file name. Terminates the loop and the program if the user presses the Enter key only.
2.Verifies that a file with the name entered exists. If the file does not exist, display an appropriate message and return to step 1.
3.Reads and displays the contents of the file.
4.Displays a count of the distinct words in the file.
5.Displays a sorted list of each of the distinct words in the file and the number of occurrences of each word. Sort the list in descending order by word count, ascending order by word.
I am pretty stuck right now and my assignment is due at midnight. Help would certainly be greatly appreciated. Thank you for your time. Here is the code I have, I will also copy paste an example test text file after it:
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream> // Needed to use files
#include <vector>
#include <algorithm> // Needed for sort from standard libraries
using namespace std;
struct WordCount{
string word; // Word
int count; // Occurence #
void iCount(){ count++; }
WordCount(string s){ word = s; count = 1;}
};
// Function prototypes
string InputText(); // Get user file name and get text from said file
string Normalize(string); // Convert string to lowercase and remove punctuation
vector<WordCount> DistinctWords(string); // Sorted vector of word count structures
bool findWord(string, vector<WordCount>); // Linear search for word in vector of structures
void DisplayResults(vector<WordCount>); // Display results
// Main
int main(int argc, char** argv) {
// Program Title
cout << "Lab 9 - Text File Word Counter\n";
cout << "-------------------------------\n\n";
// Input text from file
string buffer = InputText();
while (buffer != ""){
// Title for text file reading
cout << "\nThis is the text string read from the file\n";
cout << "-------------------------------------------\n";
cout << buffer << endl << endl;
// Build vector of words and counts
vector<WordCount> words = DistinctWords(buffer);
// Display results
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "--------------------------------------------" << endl << endl;
DisplayResults(words);
buffer = InputText();
}
return 0;
}
/***********************************************
InputText() -
Gets user file name and gets text from the file.
************************************************/
string InputText(){
string fileName;
ifstream inputFile; // Input file stream object
string str; // Temporary string
string text; // Text file string
cout << "File name? ";
getline(cin, fileName);
// Case to terminate the program for enter key
if (fileName.empty()){ exit(0);}
// Open file
inputFile.open(fileName);
if (!inputFile){
cout << "Error opening data file\n";
cout << "File name? "; cin >> fileName;
}
else{
while (!inputFile.eof()){
getline(inputFile, str);
text += str;
}
}
inputFile.close(); return text;
}
/****************************************************
Normalize(string) -
Converts string to lowercase and removes punctuation.
*****************************************************/
string Normalize(string s){
// Initialize variables
string nString;
char c;
// Make all text lowercase
for (int i = 0; i < s.length(); i++){
c = s[i];
c = tolower(c);
nString += c;
}
// Remove punctuation
for (int i = 0; i < nString.length(); i++){
if (ispunct(nString[i]))
nString.erase(i, 1);
}
// Return converted string
return nString;
}
/******************************************
vector<WordCount> DistinctWords(string) -
Sorts vector of word count structures.
*******************************************/
vector<WordCount> DistinctWords(string s){
vector<WordCount> words; // Initialize vector for words
string nString = Normalize(s); // Convert passed string to lowercase and remove punctuation
// Parse string
istringstream iss(nString);
while(iss >> nString){
string n; // Intialize temporary string
iss >> n; // Put word in n
if (findWord(n, words) == true){ continue; } // Check to verify that there is no preexisting occurence of the word passed
else{
WordCount tempO(n); // Make structure object with n
words.push_back(tempO); // Push structure object into words vector
}
}
return words;
}
/*********************************************
bool findWord(string, vector<WordCount>) -
Linear search for word in vector of structures
**********************************************/
bool findWord(string s, vector<WordCount> words){
// Search through vector
for (auto r : words){
if (r.word == s){ // Increment count of object if found again
r.iCount(); return true;
}
else // Go back to main function if not found
return false;
}
}
/***********************************************
void DisplayResults(vector<WordCount>) -
Displays results.
************************************************/
void DisplayResults(vector<WordCount> words){
// TROUBLESHOOT FIRST ERASE THIS AFTER!!!!!
cout << "Word" << setw(20) << "Count\n";
cout << "-----------------------\n";
for (auto &r : words){
cout << setw(6) << left << r.word;
cout << setw(15) << right << r.count << endl;
}
}
It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to heaven, we were all going direct the other way - in short, the period was so far like the present period, that some of its noisiest authorities insisted on its being received, for good or for evil, in the superlative degree of comparison only.
This is the example display he provided for this particular test file
You almost had it!
You just forgot to pass the 'words' vector by reference instead of by copy.
Also I included a custom comparator for the sort at the end.
#include <iostream>
#include <sstream>
#include <iomanip>
#include <string>
#include <fstream> // Needed to use files
#include <vector>
#include <algorithm> // Needed for sort from standard libraries
using namespace std;
struct WordCount{
string word; // Word
int count; // Occurence #
void iCount(){ count++; }
WordCount(string s){ word = s; count = 1;}
};
struct {
bool operator()(const WordCount& a, const WordCount& b)
{
if (a.count < b.count)
return false;
else if (a.count > b.count)
return true;
else{
if (a.word < b.word)
return true;
else
return false;
}
}
} CompareWordCount;
// Function prototypes
string InputText(); // Get user file name and get text from said file
string Normalize(string); // Convert string to lowercase and remove punctuation
vector<WordCount> DistinctWords(string); // Sorted vector of word count structures
bool findWord(string, vector<WordCount>&); // Linear search for word in vector of structures
void DisplayResults(vector<WordCount>); // Display results
// Main
int main(int argc, char** argv) {
// Program Title
cout << "Lab 9 - Text File Word Counter\n";
cout << "-------------------------------\n\n";
// Input text from file
string buffer = InputText();
while (buffer != ""){
// Title for text file reading
cout << "\nThis is the text string read from the file\n";
cout << "-------------------------------------------\n";
cout << buffer << endl << endl;
// Build vector of words and counts
vector<WordCount> words = DistinctWords(buffer);
// Display results
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "--------------------------------------------" << endl << endl;
DisplayResults(words);
buffer = InputText();
buffer = "";
}
return 0;
}
/***********************************************
InputText() -
Gets user file name and gets text from the file.
************************************************/
string InputText(){
string fileName;
ifstream inputFile; // Input file stream object
string str; // Temporary string
string text; // Text file string
cout << "File name? ";
getline(cin, fileName);
// Case to terminate the program for enter key
if (fileName.empty()){ exit(0);}
// Open file
inputFile.open(fileName);
if (!inputFile){
cout << "Error opening data file\n";
cout << "File name? "; cin >> fileName;
}
else{
while (!inputFile.eof()){
getline(inputFile, str);
text += str;
}
}
inputFile.close(); return text;
}
/****************************************************
Normalize(string) -
Converts string to lowercase and removes punctuation.
*****************************************************/
string Normalize(string s){
// Initialize variables
string nString;
char c;
// Make all text lowercase
for (int i = 0; i < s.length(); i++){
c = s[i];
c = tolower(c);
if (isalpha(c) || isblank(c))
nString += c;
}
// Return converted string
return nString;
}
/******************************************
vector<WordCount> DistinctWords(string) -
Sorts vector of word count structures.
*******************************************/
vector<WordCount> DistinctWords(string s){
vector<WordCount> words; // Initialize vector for words
string nString = Normalize(s); // Convert passed string to lowercase and remove punctuation
// Parse string
istringstream iss(nString);
string n; // Intialize temporary string
while(iss >> n){
if (findWord(n, words) == true){ continue; } // Check to verify that there is no preexisting occurence of the word passed
else{
WordCount tempO(n); // Make structure object with n
words.push_back(tempO); // Push structure object into words vector
}
}
return words;
}
/*********************************************
bool findWord(string, vector<WordCount>) -
Linear search for word in vector of structures
**********************************************/
bool findWord(string s, vector<WordCount>& words){
// Search through vector
for (auto& r : words){
if (r.word.compare(s) == 0){ // Increment count of object if found again
r.iCount(); return true;
}
}
}
/***********************************************
void DisplayResults(vector<WordCount>) -
Displays results.
************************************************/
void DisplayResults(vector<WordCount> words){
// TROUBLESHOOT FIRST ERASE THIS AFTER!!!!!
cout << "Word" << setw(20) << "Count\n";
cout << "-----------------------\n";
sort(words.begin(), words.end(),CompareWordCount);
for (auto &r : words){
cout << setw(6) << left << r.word;
cout << setw(15) << right << r.count << endl;
}
}
Consider using map for word count task
int main()
{
map<string, int> wordCount;
vector<string> inputWords = {"some", "test", "stuff", "test",
"stuff"}; //read from file instead
for(auto& s: inputWords)
wordCount[s]++; //wordCount itself
for(auto& entry: wordCount) //print all words and assosiated counts
cout << entry.first << " " << entry.second <<endl;
cout <<wordCount.size() <<endl; //thats number of distinct words
}

Find in C++ if a line from file contains a specific character

I've read the lines from a textfile and i want to check if that line contains the $ sign.
That's what i got so far:
int main() {
ifstream data_store;
string line;
data_store.open("c:\\test.txt");
while (!data_store.eof())
{
getline(data_store, line);
if (line.find("$"))
cout << "1: " << line << endl;
}
data_store.close();
system("PAUSE");
return 0;
}
Furthermore how can i output them to a file ?
To check if a line contains something using std::string::find to need to check the returned value from find to make sure it is a valid return. To do that we compare it against std::string::npos as that is what find() will return if it does not find anything. This is the reason it finds every line as std::string::npos is still considered true when evaluated as a bool. So refactoring your code you would have:
while (getline(data_store, line))
{
if (line.find("$") != std::string::npos)
cout << "1: " << line << endl;
}
I also changed the while loop as using eof is not how to control a while loop. for more information on that see Why is “while ( !feof (file) )” always wrong?
As far as outputting the string to a file see: How to write std::string to file?
It's a minor thing, but a variant of #NathanOliver's solution, is to use a for loop:
ifstream data_store("c:\\test.txt");
for ( string line; getline(data_store, line); ) {
if ( line.find("$") != string::npos )
cout << "1: " << line << endl;
}
// ...
The benefit here is that line is now local only to the loop, which is what it should be since that is the only place it is used.
I did it yesterday forgot to update.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool contains_number(const string &c);
int main()
{
int count = 0;
{
string line1[100];
ifstream myfile("D:/Users/Jarvan/Desktop/test.txt");
int a = 0;
if (!myfile)
{
cout << "Error opening output file" << endl;
system("pause");
return -1;
}
while (!myfile.eof())
{
getline(myfile, line1[a], '\n');
if (contains_number(line1[a]))
{
count += 1;
cout << line1[a] << "\n";
}
else cout << "\n";
}
}
cout << count <<endl;
system("pause");
return 0;
}
bool contains_number(const string &c)
{
return (c.find_first_of("$") != string::npos);
}