C++ Dictionary Compare with multiple strings and files - c++

I am trying to write a program that will compare an input file to a dictionary file filled with tons of words. After comparing the words, I want to output the words that are spelled incorrectly. Here is my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
void trim(string s)
{
size_t p = s.find_first_not_of(" \t");
s.erase(0, p);
p = s.find_last_not_of(" \t");
if (string::npos != p)
s.erase(p+1);
}
int main()
{
ifstream input;
ifstream words;
input.open("/Users/jordan/Desktop/CS60/Word_dictionary_check/input.txt");
if(input.fail())
{
cout<<"Input file opening failed";
exit(1);
}
words.open("/Users/jordan/Desktop/CS60/Word_dictionary_check/words.txt");
if(words.fail())
{
cout<<"Words file opening failed";
}
vector <string> wordCheck;
vector <string> misspelledWord;
string temp = "";
while(!input.eof())
{
input>>temp;
wordCheck.push_back(temp);
}
ofstream output;
output.open("/Users/jordan/Desktop/CS60/Word_dictionary_check/output.txt");
if(output.fail())
{
cout<<"Output file opening failed";
exit(1);
}
for(int j = 0; j < wordCheck.size(); j++)
{
bool dontprint = false;
while(!words.eof())
{
words>>temp;
if(temp == wordCheck[j])
{
dontprint = true;
}
}
if(dontprint == false)
{
misspelledWord.push_back(wordCheck[j]);
}
}
for(int i = 0; i < misspelledWord.size() ; i++)
{
output<<misspelledWord[i]<<endl;
}
return 0;
}
I believe something with whitespace or with the comparing of strings is a problem. Thanks for helping me out!

I can see few obvious problems. I have added comments. This should solve your problem but I am not going to write code for you.
for(int j = 0; j < wordCheck.size(); j++)
{
bool dontprint = false;
//Make your words file pointer to point to start of file. USe seek function
while(!words.eof())
{
words>>temp;
if(temp == wordCheck[j])
{
dontprint = true;
//You can break here. As once word is found, you don't need to check the word file further
}
}
if(dontprint == false)
{
misspelledWord.push_back(wordCheck[j]);
}
}

Related

I am getting a segmentation fault in this code and can't understand why?

I am trying to code a program where it takes a program as an input and prints out all the comments written in that program in a separate line.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string str;
while(getline(cin,str)) {
int i;
// cout<<str;
for(i=0;str[i]!='/' && str[i+1] !='/';i++);
//cout<<i;
for(i;str[i]!='\n';i++) {
// cout<<i;
cout<<str[i];
}
cout<<endl;
}
return 0;
}
I am getting a segmentation fault in this code and I can't understand why. This is part of a code of a problem in hackerrank https://www.hackerrank.com/challenges/ide-identifying-comments/copy-from/12957153
As commented in your question your code is wrong. First you are treating std::string object, returned by getline, as character array. Secondly your for loops never end if there is no // or \n found in input string. So obviously it will crash. Below is the modified code.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string str;
while(getline(cin,str)) {
int i;
// cout<<str;
size_t len = str.length();
const char *cstr = str.c_str();
for(i=0; (cstr[i]!='/' && cstr[i+1] !='/' && i < len); i++)
//cout<<i;
for(; cstr[i]!='\n' && i < len;i++) {
// cout<<i;
cout<<cstr[i];
}
cout<<endl;
}
return 0;
}
int main() {
while(getline(cin,str)) {
int i, len = str.size();
//always make sure that you are not accessing
//contents after your string has ended
for(i=0; i < (len - 1) && !(str[i] == '/' && str[i+1] == '/'); i++);
//note that i here might be the last alphabet
//if there's no comment
if(i < len && str[i] != '/')
i++;
//checking if str[i] != '\n' is not a good idea
//as c++ stl strings are not temrinated by '\n'
if(i < len) {
for(; i < len; i++)
cout << str[i];
cout << endl;
}
}
return 0;
}
Also note that both of the following codes won't terminate at the 4th character, c++ stl strings are not terminated by these characters.
string str = "hahahaha";
str[4] = '\n';
cout << str;
str[4] = '\0';
cout << str;
This is much easier to write and probably much faster than the other solutions to date.
#include <iostream>
int main()
{
std::string str;
while (std::getline(std::cin, str))
{
size_t loc = str.find("//");
if (loc != str.npos)
{
std::cout << str.substr(loc + 2)<< std::endl;
}
}
return 0;
}
It is also wrong.
Here is a nice, clean, and simple state machine version. Also pretty close to worst-case for speed. Thing is it's closest to being right, even though it is also wrong.
#include <iostream>
enum states
{
seeking1,
seeking2,
comment
};
int main()
{
std::string str;
while (std::getline(std::cin, str))
{
states state = seeking1;
for (char ch:str)
{
switch (state)
{
case seeking1:
if (ch == '/')
{
state = seeking2;
}
break;
case seeking2:
if (ch == '/')
{
state = comment;
}
else
{
state = seeking1;
}
break;
case comment:
std::cout << ch;
break;
}
}
if (state == comment)
{
std::cout << std::endl;
}
}
return 0;
}
Why are these approaches all wrong? Consider the line
cout << "Hi there! I am \\Not A Comment!" << endl;`
You can't just look at the \\, you also need the context. This is why the state machine above is the better option. It can be modified to handle, at the very least, states for handling strings and block comments.

Returning string from a function causing formatting issues

It's supposed to look like this: http://i.imgur.com/gko501E.png
Instead it looks like this: http://i.imgur.com/ISwqyD8.png
When I take the code out of the function and use it in the main class it works properly. However once I put it in this function the formatting problems occur, it also isn't filtering like it's supposed to. This program is supposed to take user input, store it in a string, remove all non-alphabetical characters, capitalize the vowels, and then space it out based on user defined variables given in the command line. It's also supposed to accept files as input in the command line, such as: 'program 5 8 < file'.
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
using namespace std;
//make vowels uppercase
string filter(string input)
{
size_t found = input.find_first_of("aeiou");
while (found != string::npos)
{
if (islower(input[found]))
{
input[found] = toupper(input[found]);
found = input.find_first_of("aeiou", found + 1);
}
}
//Make consonants lowercase
size_t foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ");
while (foundLower != string::npos)
{
if (isupper(input[foundLower]))
{
input[foundLower] = tolower(input[foundLower]);
foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ", foundLower + 1);
}
}
//remove punctuation
for (int i = 0, len = input.size(); i < len; i++)
{
if (!isalnum(input[i]))
{
input.erase(i--, 1);
len = input.size();
}
}
return input;
}
int main(int argc, char* argv[])
{
int wordSize;
int wordSizeCounter;
int wordCounter = 0;
int rowSize;
//char letter;
wordSize = atoi(argv[1]);
rowSize = atoi(argv[2]);
ifstream inFile;
inFile.open(argv[3]);//open the input file
stringstream strStream;
strStream << inFile.rdbuf();//read the file
string test = strStream.str();//str holds the content of the file
if (!inFile) test = cin.get() ; // Read first character
//Begin filter for files
while (!test.empty())
{
filter(test);
if (test.length() < wordSize) //make sure we don't go out-of-bounds
{
wordSize = test.length();
}
cout << test.substr(0, wordSize);
cout << " ";
if (test.length() >= wordSize) //again, make sure we don't go out-of-bounds
{
test = test.substr(wordSize);
}
else
{
test = " ";
}
wordCounter++;
if (wordCounter == rowSize)
{
cout << std::endl;
wordCounter = 0;
}
if(test.empty())
{
test = cin.get();
}
}
cout << endl;
return 0;
}

how to print out more than a character at once

I saved this word "abs" in a text file and i'm trying to make a code that can print the three characters at once in another file .. not like that
while (content[i] == 'a')
{
fout<<"a";
break;}
while (content[i] == 'b')
{
fout<<"b";
break;}
while (content[i] == 's')
{
fout<<"s";
break;}
here is the code i wrote but it doesn't print anything out..
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ofstream fout("E:\\hoss.txt");
ifstream file("E:\\test.txt");
string content;
while(file >> content)
{
for (size_t i = 0; i < content.size(); i++)
{
while (content[i] == 'ab')
{
fout<<"ab";
break;}
}}
system("pause");
return 0;
}
anyone can help??
int main()
{
ofstream fout("E:\\hoss.txt");
ifstream file("E:\\test.txt");
string content;
while(file >> content)
{
for (size_t i = 0; i < content.size(); i++)
{
if((content[i] == 'a') && (content[i+1] == 'b'))
{
fout<<"ab";
break;
}
}
}
system("pause");
return 0;
}
You have no code to print anything out. You just keep adding to the buffer, but you never flush the buffer. Get rid of the system("pause"); and just let the program end. Ending the program flushes all buffers.
while (content[i] == 'ab')
This is pretty baffling. Did you really mean ab as a character constant?

Can't fill 2d-array with sscanf_s out of a file

I search for my problem but haven't found an answer.
I try to read a table of double values from a file into an 2d-array of doubles in C++, but i can't get it to work.
The file is full of other junk i don't need and the table is parenthesized by "BEGIN TABLE" and "END TABLE". The Table has 5 doubles in a row with space delimiter and an unknown number of rows. So the File looks like this
junk
.
.
.
BEGIN TABLE
0.12145 0.23234 2.32423 1.32422 0.12345
1.34534 1.23423 5.21323 3.12313 1.22231
.
.
.
2.32422 3.23423 1.12345 4.34532 2.23423
END TABLE
So first I go through the file, search for the start and end of table and allocate memory for my array:
char sBuffer[100];
double** darrTable;
int iRes = -1;
iRes = fopen_s(&pFile, strFile, "rb");
if (iRes==0)
{
int ilines = 0;
bool beof = false;
bool bfound = false;
//get number of lines for array allocation
while(!beof)
{
fgets(sBuffer,100,pFile);
if(strstr(sBuffer,"END TABLE"))
{
bfound = false;
beof = true;
}
if(bfound) ilines++;
if(strstr(sBuffer,"BEGIN TABLE"))bfound = true;
}
darrTable = new double*[ilines+1];
for(int i = 0; i < (ilines+1); ++i) darrTable [i] = new double[5];
}
in an other code block i go through the lines again and want to readout the string, but it won't work
int ilines = 0;
bool beof = false;
bool bfound = false;
while(!beof)
{
fgets(sBuffer,100,pFile);
if(strstr(sBuffer,"END TABLE"))
{
bfound = false;
beof = true;
}
if(bfound)
{
sscanf_s(sBuffer,"%d %d %d %d %d",&darrTable [ilines][0],&darrTable [ilines][1],&darrTable [ilines][2],&darrTable [ilines][3],&darrTable [ilines][4]);
ilines++;
}
if(strstr(sBuffer,"BEGIN TABLE"))bfound = true;
}
it compiles and runs without error but all i get is an array full of 0.000000000 for darrTable. sscanf_s returs 1 witch suggest that 1 value was found, but thats all values are 0.
I use VisualStudio 2005 SP0.
Sorry for my english and thanks for your help in advance.
Use C++ style
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
std::vector<std::vector<double>> ParseFile(const std::string& filename)
{
std::vector<std::vector<double>> data;
std::ifstream file(filename.c_str());
std::string line;
while (std::getline(file, line))
{
if (line == "BEGIN TABLE")
{
while (std::getline(file, line))
{
if (line == "END TABLE")
{
break;
}
else
{
data.push_back(std::vector<double>());
std::istringstream ss(line);
double temp;
while (ss >> temp)
{
data.back().push_back(temp);
}
if (data.back().size() != 5)
{
// missing or extra data
}
}
}
break; // END TABLE missing
}
}
if (data.empty())
{
// BEGIN TABLE missing or there was no data lines
}
return data;
}

Strings with whitespace in a list?

I have this function sentanceParse with a string input which returns a list. The input might be something like "Hello my name is Anton. What's your name?" and then the return value would be a list containing "Hello my name is Anton" and "What's your name?". However, this is not what happens. It seems as if the whitespaces in the sentences are treated like a separator and therefore the return is rather "Hello", "my", "name" etc instead of what I expected.
How would you propose I solve this?
As I am not a 100% sure the problem does not lie within my code, I will add that to the post as well:
Main:
list<string> mylist = sentanceParse(textCipher);
list<string>::iterator it;
for(it = mylist.begin(); it != mylist.end(); it++){
textCipher = *it;
cout << textCipher << endl; //This prints out the words separately instead of the entire sentances.
sentanceParse:
list<string> sentanceParse(string strParse){
list<string> strList;
int len = strParse.length();
int pos = 0;
int count = 0;
for(int i = 0; i < len; i++){
if(strParse.at(i) == '.' || strParse.at(i) == '!' || strParse.at(i) == '?'){
if(i < strParse.length() - 1){
while(i < strParse.length() - 1 && (strParse.at(i+1) == '.' || strParse.at(i+1) == '!' || strParse.at(i+1) == '?')){
if(strParse.at(i+1) == '?'){
strParse.replace(i, 1, "?");
}
strParse.erase(i+1, 1);
len -= 1;
}
}
char strTemp[2000];
int lenTemp = strParse.copy(strTemp, i - pos + 1, pos);
strTemp[lenTemp] = '\0';
std::string strAdd(strTemp);
strList.push_back(strAdd);
pos = i + 1;
count ++;
}
}
if(count == 0){
strList.push_back(strParse);
}
return strList;
}
Your implementation of sentence parse is wrong, here is a simpler correct solution.
std::list<std::string> sentence_parse(const std::string &str){
std::string temp;
std::list<std::string> t;
for(int x=0; x<str.size();++x){
if(str[x]=='.'||str[x]=='!'||str[x]=='?'){
if(temp!="")t.push_back(temp);//Handle special case of input with
//multiple punctuation Ex. Hi!!!!
temp="";
}else temp+=str[x];
}
return t;
}
EDIT:
Here is a full example program using this function. Type some sentences in your console, press enter and it will spit the sentences out with a newline separating them instead of punctuation.
#include <iostream>
#include <string>
#include <list>
std::list<std::string> sentence_parse(const std::string &str){
std::string temp;
std::list<std::string> t;
for(int x=0; x<str.size();++x){
if(str[x]=='.'||str[x]=='!'||str[x]=='?'){
if(temp!="")t.push_back(temp);//Handle special case of input with
//multiple punctuation Ex. Hi!!!!
temp="";
}else temp+=str[x];
}
return t;
}
int main (int argc, const char * argv[])
{
std::string s;
while (std::getline(std::cin,s)) {
std::list<std::string> t= sentence_parse(s);
std::list<std::string>::iterator x=t.begin();
while (x!=t.end()) {
std::cout<<*x<<"\n";
++x;
}
}
return 0;
}
// This function should be easy to adapt to any basic libary
// this is in Windows MFC
// pass in a string, a char and a stringarray
// returns an array of strings using char as the separator
void tokenizeString(CString theString, TCHAR theToken, CStringArray *theParameters)
{
CString temp = "";
int i = 0;
for(i = 0; i < theString.GetLength(); i++ )
{
if (theString.GetAt(i) != theToken)
{
temp += theString.GetAt(i);
}
else
{
theParameters->Add(temp);
temp = "";
}
if(i == theString.GetLength()-1)
theParameters->Add(temp);
}
}