I am creating an object called SpellChecker that corrects the spelling of words in a string.
To check if the words are spelled correctly and if not to correct them, I have a text file of correct words (one per line). I also have a text file of words that are misspelled and their corrections separated by a tab.
My issue is reading in my text file. I have created an if statement to see if my file opens successfully. However, I believe my file should be readable and it is not. I am trying to find out why this is happening.
Here is my SpellChecker constructor:
SpellChecker::SpellChecker(string tempLanguage, string correctWordsFile,string wordCorectionsFile){
language=tempLanguage;
ifstream istream;
istream.open(correctWordsFile);
if(!istream.is_open()){
cout << "Error opening " << correctWordsFile << endl;
}
int count=0;
string temp;
while(!istream.eof()){
getline(istream,temp);
correctWords[count] = temp;
count++;
}
numCorrectWords = count;
istream.close();
istream.open(wordCorectionsFile);
if(!istream.is_open()){
cout << "Error opening " << wordCorectionsFile << endl;
}
int j=0;
int i=0;
char temp2;
while(!istream.eof()){
istream.get(temp2);
if(temp2 == '\t'){
j++;
}
else if(temp2 == '\n'){
i++;
j = 0;
}
else
wordCorections[i][j] += temp2;
}
numwordCorrections = i;
istream.close();
}
Here is my main:
int main(){
SpellChecker spellCheck("English","CorectWords.txt","WordCorections.txt");
spellCheck.viewCorrectWords();
spellCheck.viewCorrectedWords();
spellCheck.setEnd('~');
spellCheck.setStart('~');
cout << spellCheck.repair("I like to eat candy. It is greatt.");
}
The terminal returns:
"Error opening CorectWords.txt"
How can I solve this problem?
The call to library function is_open() is returning false, which could be due to one of many reasons.
Ensure that :
1. You have used correct name of the data file.
2. The data file is in the same folder as the executable of your program.
3. It has been closed by any previous program that read it.
Related
**Edit: As it turns out, it was a simple typo under the if(i==0) statement. I missed putting {} to enclose both first_nonterminal statements.
I'm creating a CFG for an assignment, but I've gotten stuck. My program is supposed to read a file (of strings) by getting the file name from the command line, and then do certain things with the contents of the file.
using namespace std;
string current, first_nonterminal;
int main(int argc, char *argv[])
{
if(argc != 2)
{
std::cout << "No file name given" << std::endl; // if there is no file name in command line
exit(1);
}
ifstream infile(argv[1]);
if(!infile)
{
std::cout << "Given file " << argv[1] << " will not open."; // if file refuses to open
exit(2);
}
string word;
for(int i = 0; infile >> word; ++i)
{
cout << word << endl; // (debug) print input word
try // check if first word is in correct format
{
if (i == 0 && word.find(':') == string::npos) // check only first word,
{
throw runtime_error("File does not have correct format.");
}
}
catch(runtime_error &e)
{
cout << "Error:" << e.what();
exit(3);
}
if (i==0)
first_nonterminal = word;
first_nonterminal.pop_back(); // remove colon
insert(word); //put string through insert() method
}
randomize(); // randomize and replace
print(); // print end result
infile.close();
}
The above code intakes a file which is formatted like so:
STMT: THIS THAT OTHER
THIS: That carpet
THIS: Atlanta
THAT: is wild
OTHER: .
OTHER: , oooh OTHER2
OTHER2: oooh OTHER2
OTHER2: !
Any word that has a colon following it is considered a nonterminal, with the words following it considered terminals. Regardless, I've figured out the issue isn't my randomize() or insert() functions, as they work perfectly if I hard-code the file into the program. My issue is the file stops being read after a certain number of strings, and I'm not sure why. For example, when I put the above's file name into the command line, it runs through, but then after it puts "That" into the insert() function, it prints "carpet" via the debug cout, and then stops.
I am trying to build a "fileUpdater" which will copy an original file into multiple directories, where a file with the same name and extension was previously found.
bool update_files(const string inputPath, const vector<string> outputPaths)
{
ifstream src(inputPath);
if(!src.is_open())
{
cout << "Unable to open input file\n" << inputPath <<endl;
return false;
}
else
{
ofstream dst;
for(unsigned int i=0; i<= outputPaths.size()-1; i++)
{
dst.open(outputPaths[i]);
try
{
dst << src.rdbuf();
dst.close();
}
catch(int e)
{
cout << "Unable to replace file\n" <<endl;
cout << outputPaths[i] <<"\n"<< endl;
cout << "Error code: " <<e<<endl;
}
}
};
src.close();
return true;
}
Exactly after executing
dst.open(outputPaths[i]);
in the second iteration, the original file opened by
ifstream src(inputPath);
gets wiped and only an empty file is copied into the remaining directories.
I also tried
dst.clear();
dst.close();
and
src.clear();
src.seekg(0,ios::beg);
before entering the next iteration, but it made no difference.
UPDATE
After trying different files, I realised the behavior depends on the input file. Above behavior appeared for .m-files (MatLab).
After testing it with .txt files, all files were wiped.
The way you're copying the file, with dst << src.rdbuf();, will leave the current file position at the end of your input file. On the second iteration, that same read won't read anything (leaving an empty copy of the file) because you're already at the end of the input file.
The solution is to seek back to the beginning of the input file before every read, using seekg. You should call tellg before reading anything (right after opening the file), then seek to that position.
auto startpos = src.tellg();
ofstream dst;
// ...
src.seekg(startpos);
dst << src.rdbuf();
None of the proposed methods work.
Neither resetting the pointer, nor pulling ifstream into the loop, which would result in opening the input file (which is not supposed to change) unnecessarily often.
It is still unclear why dst.open(outputPaths[i]); is wiping the input file. Also the exact moment of the wipe depends on used types of files.
I implemented following workaround, effectively reading the input file into a string and closing it beforehand, in order to protect it from further read/write action.
bool update_files( const string inputPath, const vector<string> outputPaths)
{
const char * in = inputPath.c_str();
ifstream src(in);
if(!src.is_open())
{
cout << "Unable to open input file\n" << inputPath <<endl;
return false;
}
else
{
string buffer;
streamsize s=src.gcount();
src.seekg(0,ios::end);
buffer.reserve(src.tellg());
src.seekg(0,ios::beg);
buffer.assign((istreambuf_iterator<char>(src)), istreambuf_iterator<char>());
src.close();
for(unsigned int i=0; i<= outputPaths.size()-1; i++)
{
const char * out = outputPaths[i].c_str();
ofstream dst(out);
try
{
dst << buffer;
dst.close();
}
catch(int e)
{
cout << "Unable to replace file\n" <<endl;
cout << outputPaths[i] <<"\n"<< endl;
cout << "Error code: " <<e<<endl;
}
}
};
src.close();
return true;
}
I am trying to load a sample text file with 8488 characters (including spaces) so I can then organise the words in the text file into alphabetical order in a GUI (To create a dictionary essentially).
The .txt file loads the text successfully however I can not read spaces from that file, it just shows all of the words with no spaces between
I have a class dictionary and within dictionary.cpp source file I attempt to load and read the text file as shown below.
void dictionary::loadFile(const char *fileName)
{
char value;
ifstream f_in(fileName);
if (!f_in)
{
cerr << "\nError loading file!" << endl;
exit(1);
}
else
{
cout << "File loaded successfully\n" << endl;
}
for (int i = 0; i < 8488; i++)
{
f_in >> value;
Memory[i] = value;
cout << Memory[i];
}
}
Can someone explain where I may have went wrong?
I'm quite new to working with classes, particularly in QT creator.
Issue has been fixed.
I used
f_in >> noskipws;
to acknowledge the white spaces.
I have created a function to write some data on a text file, and it works fine. I created another function to read in all the content of the file, and print it out for me! But, it is not working for some reason. Could any one help please?
This is my function:
void myClass::displayFile() {
char line[LINE]; //to hold the current line
file.open("data.txt", ios::app);
//keep reading information from the file while the file is open and has data
while (!file.fail() && !file.eof()) {
int lineSize; //to loope through each line
file.getline(line, LINE);
lineSize = strlen(line);
//loop through the line to print it without delimiters
for (int i = 0; i < lineSize; ++i) {
if (line[i] == ';') {
cout << " || ";
} else {
cout << line[i];
}
}
}
file.close();
file.clear();
if (file.fail()) {
cerr << "Something went wrong with the file!";
}
}
Note: The function compiles and the loop is accessible, but the line string is empty.
This is the writing function:
void myClass::fileWriter() {
file.open("data.txt", ios::app);
file << name << ";" << age << ";" << "\n";
file.close();
file.clear();
}
Silly me, the cause of your problem was staring me right in the face from the beginning, and it's the app open-mode that's the problem. It is to open the file in write mode, which means you can't read from it.
And even if you could read from the file, the cursor is placed ad the end of the file the eofbit flag would have been set inside the first iteration anyway.
If you want to read from a file, then either use std::ifstream which automatically sets the in mode if you don't specify a mode, or you have to explicitly set the in mode when opening.
I am trying to create a program in C++ using Microsoft Visual Studio 2013. The main purpose of this program is to read three different files(headlines1,headlines2, and headlines3) and put them all together to form a single file and creating a sentence within that output file. I have figured out a function that I could use, but this function only reads and prints the 3 files out onto the console window. When I try to change the cout statement into an outfile, my outfile that I created is blank... I don't know what to do or how to structure the code.
#include<fstream>
#include<iostream>
#include<cstdlib>
using namespace std;
void readingFile(string[], ifstream &); //Funtion Prototype
int main()
{
string header1[50], header2[50], header3[50]; //Declaring array with 50 elements
int size1, size2, size3;
ifstream Fin, Fin2, Fin3;
ofstream Fout;
Fin.open("Headlines1.txt"); //Reading from these 3 files.
Fin2.open("Headlines2.txt");
Fin3.open("Headlines3.txt");
if (!Fin || !Fin2 || !Fin3) //Checking for unsuccessful open
{
cout << "Input file opening failed.\n";
cin.ignore();
return 1;
}
Fout.open("testingHeadlines.txt"); //Used for unsuccessful opening output
if (!Fout)
{
cout << "Output file opening failed.\n";
cin.ignore();
return 2;
}
cout << "Building.... Editing....\n" << endl;
cin.ignore();
cout << "Headlines file 1 below:\n" << endl;
readingFile(header1, Fin); //Function call
cout << endl << endl;
cout << "Headlines file 2 below:\n" << endl;
readingFile(header2, Fin2); //Function call
cout << endl << endl;
cout << "Headlines file 3 below:\n" << endl;
readingFile(header3, Fin3); //Function call
cout << endl << endl;
cin.ignore();
return 0;
}
//the function 'readingFile'
//Pre-conditions: Reads the contents from the files of Headlines1,2,and 3
//Post-conditions: Prints out the contents.
void readingFile(string[], ifstream &infile)
{
char next;
infile.get(next);
while (!infile.eof()) //Reading until EndOfFile
{
cout << next; //Problem is here?? I would think.
infile.get(next);
}
}
I'm just not certain if where I said the "Problem is here??" is where the problem is at. Every time I change the cout to outfile(I know, I have to change the parameters within the function header) once doing that I open the outfile and the file is blank.
All the files contain random words/phrases and when put together they will make a sentence. For ex. Headlines1 contains '***Queen Jennifer*'** Headlines2 contains '***has brain surgery*'** Headlines3 contains '***after eating 30 jalapenos.*'** and When put together it should read 'Queen Jennifer has brain surgery after eating 30 jalapenos.' but the files contain more words/ phrases that what I just listed in my example.
When I run the program above I am able to read all three Headline files, but they are printed in up to down form. For example, my output on my console screen would be:
Queen
Jennifer
has brain surgery
after eating 30 jalapenos
Problem:
Getting my headlines to read from left to right.
Getting them into a output file instead of the console screen.
Help Please.
You could replace this...
void readingFile(string[], ifstream &infile)
{
char next;
infile.get(next);
while (!infile.eof()) //Reading until EndOfFile
{
cout << next; //Problem is here?? I would think.
infile.get(next);
}
}
...and the calls there-to, such as...
readingFile(header1, Fin);
...with this...
void readingFile(ifstream& infile, ofstream& fout)
{
char next;
while (infile.get(next)) //Reading until EndOfFile or error
if (next != '\n') // if not newline
fout << next; // stream to file
}
...and calls ala...
readingFile(Fin, Fout);
That way readingFile is told where to write the output, and filters out the newline characters that were causing the output to appear on different lines.
This should do the trick.
#include <fstream>
#include <string>
int main() {
// Open the three files.
std::ifstream file_1("Headlines1.txt");
std::ifstream file_2("Headlines2.txt");
std::ifstream file_3("Headlines3.txt");
// Combine into one string.
std::string content;
content += std::string(std::istreambuf_iterator<char>(file_1),
std::istreambuf_iterator<char>());
content += std::string(std::istreambuf_iterator<char>(file_2),
std::istreambuf_iterator<char>());
content += std::string(std::istreambuf_iterator<char>(file_3),
std::istreambuf_iterator<char>());
// Output the string into a single file.
std::ofstream output_file("testingHeadlines.txt");
output_file << content;
}
I'm not sure what you're wanting to do about spacing between files, but that shouldn't be too hard for you to fine-tune this code for.
one possible thing why your ouput is like this is that std::ifstream::get() that you used in infile.get(next) is a non-formatted reading method which means it will not skip white spaces and newline character \n by default. so you need to check if next value is a newline like this:
if(next == '\n') continue ;
before passing it to cout << next. Thus you will skip printing a newline in your console screen.