C++ Searching CSV file from inputted string - c++

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 """,,

Related

How to count characters from a txt file? c++

Write a C++ program that prompts the user for a filename. It should try to open the provided file. If it is invalid, continue looping and prompting until a valid file is opened. The program should read all of the tweets from the file (until EOF), then output the following analysis:
Number of hashtags.
Number of Twitter ID's
Total number of tweets
Length of the longest tweet
Length of the shortest tweet
Average length of all tweets (with 2 digits past the decimal point precision)
Up above is the assignment for me to do, and I am really confused on how I should approach this problem. So far this is the code that I have written, any steps to the right direction?
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream inputFile;
string filename;
string string;
int count = 0;
char hashtag;
cout << "Filename to open?" << endl;
cin >> filename;
inputFile.open(filename);
if (inputFile.good()){
cout << "Analysis for file tweets.txt: " << endl;
inputFile.close();
}
else
{
cout << "Error opening the file." << endl;
}
while (!inputFile.eof()){
inputFile >> hashtag;
if (hashtag == '#')
count ++;
}
cout << count << " Number of hashtags" << endl;
return 0;
}

How Do I read and Output the Contents of a File and the Number of Words it Contains?

I am attempting to write a program for homework which reads the contents of a notepad file and displays the contents and the number of words int he file. My code currently outputs nothing when I enter the name of the names of files I am using to test the program, and the input validation while loop I inserted does not function either.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
//Declare needed variables
string fileName, contents;
int wordCount = 0;
ifstream inData;
//Display program info
cout << "*** A SIMPLE FILE PROCESSING PROGRAM ***" << endl;
//Prompt user input
cout << "Enter a filename or type quit to exit: ";
cin >> fileName;
inData.open(fileName.c_str());
//Inform the user when their input is invalid and ask them to input another
file name
while (!inData)
{
inData.clear();
inData.ignore(200, '\n');
cout << "File not found. Please type a correct file name." << endl;
cin >> fileName;
inData.open(fileName.c_str());
}
inData >> contents;
//Read and output the contents of the selected file
while (inData)
{
cout << fileName << " data\n";
cout << "***********************" << endl;
inData >> contents;
wordCount++;
cout << contents << endl;
inData >> contents;
}
//Display the number of words in the file
cout << "***********************" << endl;
cout << fileName << " has " << wordCount << " words." << endl;
inData.close();
return 0;
}
The code compiles in its current state [but does not produce the desired outcome.
I will show you one of the many possible solutions.
But I would not recomend, to check the validity of a filename in a loop. You will give the user no chance to escape. Hence, I propose to open the file, and, if that does not work, show an error message and quit.
Then, what sounds easy in the beginning like, count the words, is not really that easy. What is a word? Characters only, or characters mixed with digits or even an underscore in it like for C++ variable names? Needs to be defined.
Additionally you may have separators like commas or one and more other white spaces. So a line like "Hello,,,,World" cannot be so easily counted. If you try to read the 2 words, then you will see a surprise.
std::string s1{};
std::string s2{};
std::istringstream iss("Hello,,,,World");
iss >> s1 >> s2;
Will read everything in s1!
The solution is that we define clearly what a word is. And this we will do with a std::regex. In the below example we use characters, digits and _
Then we use the regex_iterator to find all occurences of the regex (the word) in the line. We substract the end from the beginning with std::distance, which will give us the count of the words.
Then we give an output to the user in whatever format.
It may seem complicated. But it is precise. And rather flexible. Try to anaylze line by line and you will understand it.
Please see:
#include <iostream>
#include <string>
#include <regex>
#include <fstream>
#include <iomanip>
int main()
{
// Get a filename from the user
std::cout << "Enter a filename:\n";
std::string filename{}; std::cin >> filename;
// Try to open and read the file
std::ifstream fileStream(filename);
if (fileStream) {
// We will count all words
size_t numberOfWordsOverall{ 0 };
// We will also count the lines in the file
size_t lineCounter{ 1 };
// Define, what a word is. In this case: Characters, Digits and _
std::regex regexForWord("[\\w\\d_]+");
// Read all lines in file
std::string line{};
while (std::getline(fileStream, line)) {
// Count the numbers of words in one line
const size_t numberOfWordsInLine = std::distance(
std::sregex_token_iterator(line.begin(), line.end(), regexForWord, 1),
std::sregex_token_iterator()
);
// Update the overall word counter
numberOfWordsOverall += numberOfWordsInLine;
// Show result to user
std::cout << "# " << std::left << std::setw(2) << lineCounter++ << " (Words in line: "<< std::setw(2) << numberOfWordsInLine <<
" Words overall: " << std::setw(4) << numberOfWordsOverall << ") Line content --> " << line << '\n';
}
}
else {
std::cerr << "Could not open file '" << filename << "'\n";
}
return 0;
}
Hope this helps . . .

Issue printing .txt file in program C++

I have a program that takes a text file and list the words and how many times they are used. It works but I can't figure out how to print out the text file. Above the sorted words and how many times they appear, I want to display the text from the file. How would I do that? I tried several things but it either does nothing or screws up the rest of the code saying there are 0 unique words. And lastly how would print out the results so they are more ... table -ish...
/*
Something like this:
Word: [equal spaces] Count:
ask [equal spaces] 5
anger [equal spaces] 3
*/
Thank you for any assistance you can provide me.
#include <iterator>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <cctype>
using namespace std;
string getNextToken(istream &in) {
char c;
string ans="";
c=in.get();
while(!isalpha(c) && !in.eof())//cleaning non letter charachters
{
c=in.get();
}
while(isalpha(c))
{
ans.push_back(tolower(c));
c=in.get();
}
return ans;
}
string ask(string msg) {
string ans;
cout << msg;
getline(cin, ans);
return ans;
}
int main() {
map<string,int> words;
ifstream fin( ask("Enter file name: ").c_str() ); //open an input stream
if( fin.fail() ) {
cerr << "An error occurred trying to open a stream to the file!\n";
return 1;
}
string s;
string empty ="";
while((s=getNextToken(fin))!=empty )
++words[s];
while(fin.good())
cout << (char)fin.get(); // I am not sure where to put this. Or if it is correct
cout << "" << endl;
cout << "There are " << words.size() << " unique words in the above text." << endl;
cout << "----------------------------------------------------------------" << endl;
cout << " " << endl;
for(map<string,int>::iterator iter = words.begin(); iter!=words.end(); ++iter)
cout<<iter->first<<' '<<iter->second<<endl;
return 0;
}
I would just use a simple for loop like this:
for (int x = 0; x < words.size(); x++){
cout >> words[x] << endl
}
And then modify from there to get your desired format.
I did notice though, that you are not returning a value for main in all paths of the above code, which should give a compile time error, but did not when I compiled it, for some reason. I would remind you that you need to have a return value for main. Unless I am misunderstanding your question. I could not run this program without creating a sample file, and so could not test it without extra work. But the program did compile. I did not expect to, because of the missing return statement. If you can make this reproduce your error without me having to create a sample file of words, ei insert the list of words into the code and minimally reproduce the error, I would be able to help you better. As it is, I hope that I helped you.
Something like this should make it:
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <string>
int main( int argc, char* argv[] )
{
std::string file;
std::cout << "Enter file name: ";
std::cin >> file;
std::fstream in( file.c_str() );
if ( in.good() )
{
std::unordered_map<std::string, int> words;
std::string word;
//Use this to separate your words it could be '\n' or anything else
char cSeparator = ' ';
while ( in >> word )
{
//Print the word
std::cout << word << cSeparator;
++words[word];
}
std::cout << std::endl;
//Headers Word and Count separated by 2 tabs
std::cout << "Word:\t\tCount:" << std::endl;
for ( auto& w : words )
std::cout << w.first << "\t\t" << w.second << std::endl;
}
in.close();
return EXIT_SUCCESS;
}
However this is assuming that the text file only contains the words, if you have other kind of stuff there, you should be able to filter it as you want.

Min/max Logic and file read error

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

Cout doesn't print on display (console)

so i have a code that's supposed to find a string of characters in a certain .txt file, if the input is in the file, it says "yey i found it" but when it isnt, its supposed to say "didnt find anything", but it just skips that step and ends.
I'm a beginner so sorry for any obvious mistakes.
#include <stdio.h>
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{
setlocale(LC_ALL, "");
string hledat;
int offset;
string line;
ifstream Myfile;
cout.flush();
cout << "Welcome, insert the string to find in the file. \n \n \n" << endl;
cin.get();
cout.flush();
Myfile.open("db.txt");
cin >> hledat;
if (Myfile.is_open())
{
while (!Myfile.eof())
{
getline(Myfile, line);
if ((offset = line.find(hledat, 0)) != string::npos)
{
cout.flush();
cout << "Found it ! your input was : " << hledat << endl;
}
}
Myfile.close();
}
else
{
cout.flush();
cout << "Sorry, couldnt find anything. Your input was " << hledat << endl;
}
getchar();
system("PAUSE");
return 0;
}
There are three possible cases.
The file was not successfully opened.
The file was successfully opened, but the string was not found.
The file was successfully opened, and the string was found.
You have a printout for cases 1 and 3, but not 2.
By the way, your loop condition is wrong. Use the result of the call to getline, which is the ostream object itself after the read attempt.
while (getline(MyFile, line))
{
...
}
The loop will terminate upon an unsuccessful read attempt, which will happen after you read the last line. The way you have it, you will try to read after the last line, which will be unsuccessful, but you will still try to process that non-existent line because you don't check eof until the loop starts over.
Just comment out //cin.get(); , you dont need it.
Output:
Welcome, insert the string to find in the file.
apple
Found it ! your input was : apple
Other than that, it works like a charm.
Corrected code:
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{
setlocale(LC_ALL, "");
string hledat;
int offset;
string line;
ifstream Myfile;
cout.flush();
cout << "Welcome, insert the string to find in the file. \n \n \n" << endl;
//cin.get(); <----- corrected code
cout.flush();
Myfile.open("db.txt");
cin >> hledat;
if (Myfile.is_open())
{
while (!Myfile.eof())
{
getline(Myfile, line);
if ((offset = line.find(hledat, 0)) != string::npos)
{
cout.flush();
cout << "Found it ! your input was : " << hledat << endl;
}
}
Myfile.close();
}
else
{
cout.flush();
cout << "Sorry, couldnt find anything. Your input was " << hledat << endl;
}
getchar();
system("PAUSE");
return 0;
}