C++ Searching for a word in a CSV file - c++

I am trying to create a program that stores data from a CSV file and then searches it for key words.
I have this code, and there are no errors shown, but it wont run the program past asking for 'Enter word: '
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(){
vector<string> student(860);
vector<string> question(860);
vector<string> answer(860);
int count = 0;
string word;
ifstream file("data2.csv");
if (!file.is_open())
cerr << "File not found" << endl;
while (file.good()){
for (int i = 0; i < 860; i++){
getline(file, student[i], ',');
getline(file, question[i], ',');
getline(file, answer[i], ',');
}
}
cout << "Enter word: ";
cin >> word;
for (int j = 0; j < 860; j++){
if (answer[j].find(word) != std::string::npos){
cout << student[j] << question[j] << answer[j] << endl;
count++;
}
}
cout << count;
return 0;
}

In order to get std::cin to contain the exact string (multiple words?) that the user inputs, you can use std::getline() which will support more than one word specified by the user. It's not clear from your problem statement if this is what you want or not. Otherwise I don't see a problem with just using std::cin if all you're looking for is a single word of input.
std::string match;
std::cout << "Enter the exact string to search for: ";
std::getline(std::cin, match);
std::cout << "\nSearching for \"" << match << "\"" << std::endl;
Also, in your for loop for searching the answer strings, you should prefer to use the built in size of the vector you're looping through as opposed to a hard coded value.
for ( size_t j = 0; j < answer.size(); ++j )
{
std::size_t found = answer[j].find(match);
if (found != std::string::npos)
{
std::cout << "found \"" << match
<< "\" starting at character " << found << std::endl;
count++;
}
}
std::cout << "occurrences of match criteria: " << count << std::endl;

the error is in getline, the first call to it, extracts the word until the comma the second call until the 2nd comma, the 3r call to third comma past the to the next new line (the next student's name).
So the next iteration in the getline call, will fetch the question as the students name then the answer as the question then the next students name as the answer, a total mess!!! ;) So you will never find the word you are looking for, thus no result. Get it?
to fix this, try to change the last getline to getline(file, answer[i]);

So, I know this is not the best way to solve the problem. But, in a time crunch I was able to fix these few errors and add a system("pause"); at the end of my code so that it would let me see the results.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(){
vector<string> student(860);
vector<string> question(860);
vector<string> answer(860);
int count = 0;
string word;
ifstream file("data2.csv");
if (!file.is_open())
cerr << "File not found" << endl;
while (file.good()){
for (int i = 0; i < 860; i++){
getline(file, student[i], ',');
getline(file, question[i], ',');
getline(file, answer[i], '\n');
}
}
cout << "Enter word: ";
cin >> word;
for (int j = 0; j < 860; j++){
if (answer[j].find(word) != std::string::npos){
cout << student[j] << question[j] << answer[j] << endl;
count++;
}
}
cout << count << endl;
system("pause");
return 0;
}

Related

C++ UTF-8 Reading text file, counting characters and outputing results to another file. ‘ gets saved as nothing, but is counted. ā and € appears

I have a task in C++ to read from a UTF-8 text file, count the characters, and save the character + count in a tsv.
I use everywhere wstring, wifstream, and wofstream.
In the terminal, there are many empty spaces when checking everything, but when outputting to tsv everything is overall fine except for 3 things.
‘ when saved appears as nothing, but its amount is counted correctly.
From nowhere ā and € appear. They are counted as the same amount, but they are not present in the original text at all.
What might be the cause of these issues?
The code is a bit crude but looks like this currently
#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
vector <wchar_t> characters;
vector <int> counter;
string filename;
string param;
cout << "Please input the filename: ";
cin >> filename;
cout << "Please, if you want to convert everything to lowercase, input 'lower', else input 'No': ";
cin >> param;
wifstream inFile;
wofstream endFile("dancing_men_char_frequency.tsv");
inFile.open(filename);
wstring Tfile;
int checker;
//inFile >> Tfile;
while(getline(inFile, Tfile)) {
//wcout << Tfile;
//sort(Tfile.begin(), Tfile.end());
if(param == "lower"){
transform(
Tfile.begin(), Tfile.end(),
Tfile.begin(),
towlower);
}
for(int i = 0; i < Tfile.length(); i++){
if(find(characters.begin(), characters.end(), Tfile[i]) != characters.end())
{
if(isblank(Tfile[i])){}else{
checker = 0;
while(characters[checker] != Tfile[i]){
checker++;
}
counter[checker] += 1;
}
}else{
if(isblank(Tfile[i])){}else{
characters.push_back(Tfile[i]);
counter.push_back(1);
}
}
}
}
int sum = 0;
for(int i = 0; i < characters.size(); i++){
wcout << characters[i] << " ";
cout << counter[i] << " " << i << endl;
sum += counter[i];
endFile << characters[i] << '\t' << counter[i] << '\n';
}
cout << sum << endl;
//wcout << Tfile;
//sort(Tfile.begin(), Tfile.end());
//wcout << Tfile;
endFile.close();
inFile.close();
return 0;
}

String doesn't want to store a 2700 character word

I'm trying to make a program that prints all the numbers from 100-999. After that you get to choose how many numbers you want to find. Then you type the number's position and it will be outputed.
There is one problem. The string, named str, stops storing at the number 954.
Here's the code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
//Prints to myFile the numbers from 100 to 999 without a space in between. Like this: 100101102...999
ofstream myFile("numere.txt");
for(int i = 100; i <= 999; i++)
myFile << i;
//Makes the string str to store the line: 100101102103...999. But only stores until 954 (100101102..954)
ifstream myFileRead("numere.txt");
string str;
while(getline(myFileRead, str))
cout << str << endl;
//Ouputs the lenght that should be 2700 but is instead 2565
cout << endl;
cout << "String legth: " << str.size() << endl;
cout << endl;
int n, k;
cout << "Enter how many numbers do you want to find: ";
cin >> n;
for(int i = 1; i <= n; i++){
cout << "Enter number position(it starts from 0) : ";
cin >> k;
cout << "Here's the number on position " << k << ": " << str.at(k);
cout << endl;
}
system("pause>0");
}
Thanks for your attention. I’m looking forward to your reply.
C++ streams are buffered. When you use << to write to a file it is not immediately written to the file.
Try to close or flush the ofstream before you read from it:
myFile.close(); // or...
myFile.flush();
For more details I refer you to flush() and close().
PS: Actually it is rather rare that you need to close a fstream explicitly. You wouldn't need to do it when you used seperate functions for writing and reading:
void write_to_file() {
std::ofstream myFile("numere.txt");
//...
}
void read_from_file() {
std::istream myFile("numere.txt");
//...
}
Because the destructor of ofstream already closes the file.

c++ input for-loop followed by another input

c++ Microsoft visual studio on a windows.
im very new to coding. currently going through Programming -- Principles and Practice Using C++ by Stroupstrup and I came across a difficulty. I am to create a "score chart" with vector name and vector score from the user input. I used for-loop to get the input. now I am to modify the program so that with 2nd input from the user I can search the list and "cout<<" the score for a person. the problem is the the program completely ignores the 2nd "cin>>" command.
I search online and could not find a reasonable answer to this problem. Is there any special interaction between a for-loop input being terminated and another input (not looped)
syntax:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> name;
vector<int> score;
string temp2;
int i;
for (string temp; cin >> temp >> i;) //input terminated with "Ctrl+Z"
name.push_back(temp), score.push_back(i);
for (int i = 0; i < name.size(); ++i) {
for (int j = i + 1; j < name.size(); ++j) {
if (name[i] == name[j]) {
name[j] = "error";
score[j] = 0;
}
}
}
for (int i = 0; i < name.size(); ++i) {
cout << name[i] << "------" << score[i] << "\n";
}
cout << "name"; //this line shows in the console
cin >> temp2; //but I cannot prompt the user to input again?
return 0;
}
CTRL-Z is interpreted as "End-Of-File", such that any subsequent access to this stream will not read in items any more. The only secure way is to change program logic such that the list of names is terminated by, let's say "END", and not a CTRL-Z. Then you can continue in a save manner.
Often input from a terminal is read in line by line and parsed afterwards. This makes error handling easier. See the following code following such an approach:
#include <sstream>
int main() {
string line;
map<string,int> scoreboard;
cout << "enter name score (type END to finish):" << endl;
while (std::getline(cin, line) && line != "END") {
stringstream ss(line);
string name;
int score;
if (ss >> name >> score) {
scoreboard[name] = score;
} else {
cout << "invalid input. Type END to finish" << endl;
}
}
cout << "enter name:" << endl;
string name;
if (cin >> name) {
auto item = scoreboard.find(name);
if (item != scoreboard.end()){
cout << "score of " << name << ":" << item->second << endl;
}
else {
cout << "no entry for " << name << "." << endl;
}
}
}

First word of a phrase is dropped when I try and put it in a vector?

Sorry for the vague header. Difficult to describe. I am trying to get a phrase from the user and put that phrase into a vector, word by word, separated by spaces. For some reason when the vector is printed it completely leaves out the first word of the phrase, if that makes sense. Here's the code I have so far:
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
do{
cin >> phraseInput;
if(phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
}
}while(phraseInput != stop);
}
Here you have taken input for two times only first one skipped
Now you should change this
else{ string temp;
getline(cin, temp);
phraseInput+=temp;
istringstream iss(phraseInput);
//.....
I think I found your answer
I tested your code with the phrase "this is line."
Your variable "phraseInput" first take "this" string.
After getline(cin, phraseInput) line.
Your variable "phraseInput" take "is line" string.
Therefore when it prints, it simply skips the first keyword.
Result is: the first string "this" is missing
I think in this way: You take two input from user.
Therefore I thought " What happens if I commented first cin? "
After commented on your first cin. I got all the string in variable "phraseInput"
Result is:
Then I thought "do while" loop also unnecessary, since it prints any word it took from user.
I also commented your "do while" loop
Here is the final version of your code.
#include <vector>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
void printVector(vector<string>& words){
cout << "Print words: " << endl;
for (int i = 0; i < words.size(); i++){
if (i < words.size()){
cout << words[i] << ", ";
}
else
cout << words[i];
}
cout << endl;
}
int main(){
string phraseInput;
string stop = "done";
/*do{
cin >> phraseInput;
if (phraseInput == stop){
cout << "Program finished." << endl;
return 0;
}
else {*/
getline(cin, phraseInput);
istringstream iss(phraseInput);
vector<string> words;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(words));
printVector(words);
//}
system("pause");
//} while (phraseInput != stop);
}

Search word not found in a vector?

I'm implementing a function where the user can search for a word in a vector. The only problem is, my search function is only finding certain words and I'm not sure why.
ifstream in("testdata.txt");
string word1;
vector<string> individual_words;
while (in >> word1)
{
individual_words.push_back(word1);
}
Inside the file testdata.txt is:
Hello how are you
Good are you well?
Snazzy piece of toast
Here is the code where I compare the two words.
string search_word;
while (cin >> search_word)
{
for (int f=0; f < individual_words.size(); f ++)
{
cout << "individual words: " << individual_words[f] <<endl;
cout << "search word: " << search_word;
if (search_word == individual_words[f])
{
cout << " FOUND THE SAME WORD\n!";
break;
}
}
}
For some reason it's only catching certain words in a .txt file and I'm not exactly sure why. I've looked at it and it looks like it ignores the first word and it ignores every last word on each sentence.
Your vector will have duplicates, so it will only find the first occurrences of the words "are" and "you" before your loop breaks. Logically, there is nothing else wrong in this section of code, though it would be better written as:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
{
// simplified for demonstration purposes
string test = "Hello how are you\nGood are you well?\nSnazzy piece of toast";
istringstream iss(test);
vector<string> words;
copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(words));
string search_word;
while (cin >> search_word)
{
// this works, but is unnecessary
/*for (int f=0; f < words.size(); f ++)
{
cout << "individual words: " << words[f] <<endl;
cout << "search word: " << search_word;
if (search_word == words[f])
{
cout << " FOUND THE SAME WORD\n!";
break;
}
}*/
// this is a better approach
vector<string>::iterator it = find(words.begin(), words.end(), search_word);
if (it != words.end())
{
cout << "Found the word: " << *it << endl;
}
else
{
cout << "Not found!" << endl;
}
}
return 0;
}