Unusual/Wrong Behavior of C++ Program - c++

My code is intended to tell the user whether the string entered is a keyword in c++.
I am reading the keywords from a file into a set and then checking if the user supplied string is in it.
#include <iostream>
#include <string>
#include <set>
#include <algorithm>
#include <fstream>
using namespace std;
int main()
{
set<string> key;
fstream fs;
string b;
fs.open("keywords.txt",fstream::in);
while(getline(fs,b))
key.insert(b);
b.clear();
for(auto x:key)
cout << x << endl;
cout << "Enter String user\nPress exit to terminate\n";
while(getline(cin,b))
{
if(b == "exit")
break;
if(key.find(b) != key.end())
cout << "This is a keyword\n";
else
cout << "This is a not a keyword\n";
b.clear();
}
fs.close();
}
The keywords.txt file is just a list of keywords and can be obtained from here
The problem is that my program reads all keywords correctly but for some of them such as false,public it cannot find them in the set.
i.e. when I enter false as user input
it says, "This is not a keyword."

Considering your input file, I think you have some keyword names with trailing spaces.
"catch "
"false "
You can trim the strings before inserting in the set to remove spaces, using boost::trim or your own trim (see this question for instance.)
(If you want some advice as for your code:
You can use std::ifstream like this for input file streams:
std::ifstream file( "keywords.txt" );
You do not need to call .close() at then of the scope, it will be done automatically thanks to RAII.
You should not reuse the same std::string objects for every purpose, you can declare new string objects close to their use. You should give them better names like "line" instead of "b". Doing this, you don't need to call ".clear()" for your strings.
Every line has just one word, you could use while(fs>>b) the >> will ignore the spaces (from moldbinlo & wangxf comments)
)

Related

I don't understand how to use toupper and isalpha with .txt file string input

My program is largely incomplete, but I assumed that using toupper to modify the strings following their input from the textfile would work to change all the characters of said string to uppercase. I read that works with type int, or what I assume is Ascii in this case. But I'm not really sure where to go from here. What is the most efficient means of converting and checking strings from a textfile as far as beginner C++ goes?
I've googled this issue and found a wide variety of ways, such as using std::transform, but I feel like my instructor would only want us using methods taught from our book 'Starting out with C++' by Tony Gaddis. Unfortunately I'm not finding any reference in my book where toupper is being used on textfile input, only on char values. For education's sake I'm hoping you have an idea of what I should be using here and why. I welcome recommended reading.
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
string text;
ifstream textFile;
int ch;
textFile.open("letter_count.txt", ios::in);
toupper(textFile.get());
isalpha(textFile.get());
if (textFile)
{
// Read an item from the file.
getline(textFile, text);
// While the last read operation
// was successful, continue.
while (textFile)
{
if (textFile)
// Display the last item read.
cout << text << endl;
// Read the next item.
getline(textFile, text);
}
// Close the file.
textFile.close();
}
else
{
cout << "ERROR: Cannot open file. \n";
}
cout << "The most common letter is " " with " " occurances. \n";
cout << "The least common letter is " " with " " occurances. \n";
system("pause");
}
I'm getting no results from using toupper.
That is because toupper takes only one int value. Notice here:
http://www.cplusplus.com/reference/cctype/toupper/?kw=toupper
You have to loop over every char in your string in order to convert it.

Why string receives numbers in this while loop?

A string is a variable-length sequence of characters. Why does it receive anything and prints it out?
#include <iostream>
#include <string>
using namespace std;
int main (){
string word;
while (cin >> word){
cout << word << endl;
}
return 0;
}
In this program, we read into a string, not an int. How can I fall out of this while loop i.e hit an invalid input?
Reading into a string will not fail, all input is valid. You may add any validation you like once the string is read.
Your question is a little vague, but if you're asking how to end the loop you can do it with an end-of-file. On Linux this you can generate one from the console with Control-D, and on Windows with Control-Z plus Enter.
Because you are taking the input in a string and string is a sequence of characters .so it takes anything you input from the keyboard either it is number or alphabet or any special character .
How can I check for invalid input?
If you could define what you consider to be "invalid input" you can filter for it in one of the std::string helper methods. In your example you eluded to numbers not being strings... so if you want to do something with pure numbers...
#include <iostream>
#include <string>
using std::string;
using std::cin;
using std::cout;
using std::endl;
int main (){
string word;
while (cin >> word){
bool isNumber = (word.find_first_not_of("0123456789") == std::string::npos);
if (isNumber){
cout << "it's a number! " << word << endl;
}else{
cout << word << endl;
}
}
return 0;
}

How to read names into a pointer array and output them?

Here is what I got so far:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int characterList = 0;
char* dynamo = new char[1000];
char* buffer = dynamo;
ifstream input("wordlist.txt");
if (input.is_open())
{
input >> dynamo[characterList];
while (input.eof())
{
characterList++;
input >> dynamo[characterList];
cout << dynamo[characterList];
}
}
else
{
cout << "File not opened" << endl;
}
return;
}
I'm a beginner so I do apologize if this looks like terrible coding practice. I created a text file with a quote from Bill Cosby that I'm trying to read one word at a time. The quote is "I don't know the key to success, but the key to failure is trying to please everybody." I'm trying to read one word at a time from a text document ignoring punctuation. I know there are a lot of questions similar to this, but they are using code that I have not learned so I'm sorry for having a repeating question. I have not learned getline (I used cin.getline) and #include <string>.
Edit: I forgot to mention, so I'm sorry for not doing so earlier, but I'm studying dynamic memory allocation which is why I'm using the new char[1000].
I'd suggest you to use std::string instead of manually allocating buffers on the heap with new[] and trying to read text manually from the file into those buffers (and don't forget to free the buffer with proper delete[] calls!).
C++ input stream classes like std::ifstream can simply read text into std::string instances thanks to a proper overload of operator<<.
The syntax is as simple as:
string word;
while (inFile >> word)
{
cout << word << endl;
}
Here's a complete compilable sample code for you to experiment and learn:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream inFile("test.txt");
if (inFile.is_open())
{
string word;
while (inFile >> word)
{
cout << word << endl;
}
}
else
{
cout << "Can't open file." << endl;
}
}
This is the output I got on a test text file having the content specified in your question:
I
don't
know
the
key
to
success,
but
the
key
to
failure
is
trying
to
please
everybody.
NOTE
Of course, once you have your words read into a std::string instance, you can store them in a container like std::vector<std::string>, using its push_back() method.
I would do something like this:
#include <iostream>
#include <string>
#include <fstream>
int main() {
std::string array[6];
std::ifstream infile("Team.txt");
std::string line;
int i = 0;
while (std::getline(infile, line)) {
array[i++] = line;
}
return 0;
}
based on this answer.
Here, we assume we have to read 6 lines from the file "Team.txt". We use std:::getline() and we put inside a while so that we read all the file.
At every iteration, line holds the current line of the file read. Inside the body we store it in array[i].

Creating a File Parser in C++

I am trying to create a parser class that will parse a file based on " " and place the words into a linked list.
class FileReader
{
public:
FileReader(char* file)
{
ifstream fout (file, ifstream::in);
string hold;
while (fout.good())
{
getline (fout, hold, " ");
cout << hold;
}
fout.close();
}
};
The function getline(fout, hold, " ") is not recognizing " " as the delimiter.
I have not coded the linked list part as of yet so this is just the parsing part of the program.
Also would there be a better way to create a parser?
It should just work like this:
#include <fstream>
#include <iterator>
#include <list>
#include <string>
std::ifstream infile(file);
std::list<std::string> words(std::istream_iterator<std::string>(infile),
std::istream_iterator<std::string>());
Now words is your linked list of whitespace-separated tokens.
Lesson: The best kind of code is the one you don't have to write.
The last parameter in getline is a char not a string. Looking at your current code, you want getline(fout,hold,' ') or just getline(fout,hold) -- *if you want the whole line.
*: edit

How to read the string into a file C++

i have a little problem on writing the string into a file,
How can i write the string into the file and able to view it as ascii text?
because i am able to do that when i set the default value for str but not when i enter a str data
Thanks.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
fstream out("G://Test.txt");
if(!out) {
cout << "Cannot open output file.\n";
return 1;
}
char str[200];
cout << "Enter Customers data seperate by tab\n";
cin >> str;
cin.ignore();
out.write(str, strlen(str));
out.seekp(0 ,ios::end);
out.close();
return 0;
}
Please use std::string:
#include <string>
std::string str;
std::getline(cin, str);
cout << str;
I'm not sure what the exact problem in your case was, but >> only reads up to the first separator (which is whitespace); getline will read the entire line.
Just note that >> operator will read 1 word.
std::string word;
std::cin >> word; // reads one space seporated word.
// Ignores any initial space. Then read
// into 'word' all character upto (but not including)
// the first space character (the space is gone.
// Note. Space => White Space (' ', '\t', '\v' etc...)
You're working at the wrong level of abstraction. Also, there is no need to seekp to the end of the file before closing the file.
You want to read a string and write a string. As Pavel Minaev has said, this is directly supported via std::string and std::fstream:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
std::ofstream out("G:\\Test.txt");
if(!out) {
std::cout << "Cannot open output file.\n";
return 1;
}
std::cout << "Enter Customer's data seperated by tab\n";
std::string buffer;
std::getline(std::cin, buffer);
out << buffer;
return 0;
}
If you want to write C, use C. Otherwise, take advantage of the language you're using.
I can't believe no one found the problem. The problem was that you were using strlen on a string that wasn't terminated with a null character. strlen will keep iterating until it finds a zero-byte, and an incorrect string length might be returned (or the program might crash - it's Undefined Behavior, who knows?).
The answer is to zero-initialize your string:
char str[200] = {0};
Supplying your own string as the value of str works because those in-memory strings are null-terminated.