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

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

Related

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.

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.

Why is my vector printing as blanks when values have been entered through a file?

I am trying to store strings from a file into a vector containing an array. The following is my way of getting information into the vector:
{
string line;
int nooflines = 0;
ifstream myFile("SongListFile.txt");
while (getline(myFile, line)) {
nooflines++;
}
song temp;
myFile.open("SongListFile.txt");
for (int i = 0; i < nooflines; i++) {
myFile >> temp.title;
myFile >> temp.artist;
myFile >> temp.genre;
songs.push_back(temp);
}
myFile.close();
}
And this is how im trying to print this information:
void SongList::ViewSongList() {
int last_element_position = songs.size() - 1;
for (int i = last_element_position; i >= 0; i--)
{
cout << "\"" << songs[i].title << "\" by " << songs[i].artist << " (" << songs[i].genre << ")" << endl;
}
Why are the strings printing as if they contain nothing? Two of the templates print when there are two lines of text, so my problem is the strings not being stored in my array.
}
Apart that you could do the reading in one pass, as indicated in comments and other answers, the way you are "re-opening" the file is not correct. After the first pass a flag of your ifstream has been set when reaching the end of the file. Opening again the file (without closing) wont clear the flag.
You need either to myFile.close() before re-opening, or alternatively clear the flags then seek to the beginning:
myFile.clear(); // clear the flags
myFile.seekg(0, ios::beg); // seek back to beginning for the second pass
You don't need to count the number of lines in the file at all. You can do it in one pass :
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct Song { string title, artist, genre; };
int main() {
ifstream myFile;
myFile.open("songList.txt");
string aLine;
vector<Song> songs;
while(getline(myFile, aLine)) {
stringstream sin(aLine);
Song aSong;
sin >> aSong.title >> aSong.artist >> aSong.genre;
songs.push_back(aSong);
}
for(int i = 0; i < songs.size(); i++)
cout << "\"" << songs[i].title << "\" by " << songs[i].artist << " ("
<< songs[i].genre << ")" << endl;
return 0;
}

Writing to a file with fstream and cstring

#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char filename[20] = "filename";
char userInput;
ofstream myFile;
cout << "Enter filename: ";
cin.getline(filename, sizeof(filename));
myFile.open(filename);
if(myFile.fail())
{
cout << "Error opening file: "
<< filename << "\n";
return 1;
}
cout << "Add text to the file: ";
cin.get(userInput);
while(cin.good() && userInput)
{
myFile.put(userInput);
cin.get(userInput);
}
myFile.close();
return 0;
}
Im having trouble terminating the input without force quiting it(It still writes to the file).
This is what I am supposed to do
Receives a line of input from the user, then outputs that
line to the given file. This will continue until the line input
by the user is “-1” which indicates, the end of input.
however I cannot work out the -1 part. Any help would be greatly appreciated everything else seems to work.
You're making things a bit more complicated than they need to be. Why C strings instead of std::string, for example? Using the right (standard-provided) classes generally leads to shorter, simpler and easier-to-understand code. Try something like this for starters:
int main()
{
std::string filename;
std::cout << "Enter filename" << std::endl;
std::cin >> filename;
std::ofstream file{filename};
std::string line;
while (std::cin >> line) {
if (line == "-1") {
break;
}
file << line;
}
}
First of all, the assignment asks to read a line from the user, character-wise input by get() shouldn't be the function to use. Use the member function getline() as you did to recieve the file name and use a comparison function to check against -1:
for (char line[20]; std::cin.getline(line, sizeof line) && std::cin.gcount(); )
{
if (strncmp(line, "-1", std::cin.gcount()) == 0)
break;
myFile.write(line, std::cin.gcount());
}

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