I have a text file that contains several words, all separated by spaces. I'm trying to read the file and then put it into an array, so that each word is a separate value in said array. I'm using this code, but when I run my program, it doesn't display anything (like it should.)
ifstream file ("words.txt");
if(file.is_open())
{
string wordArray[100];
for(int i = 0; i < 100; ++i)
{
file >> wordArray[i];
cout << i;
}
cout << "File is open.";
}
Nothing displays at all. I'm doing this in a void function, which isn't being passed anything currently, but I don't think that has anything to do with it. The code should at least display "File is open" or any number from 1 to 100, but I don't get anything. I don't understand why this isn't working, as I'm including iostream, string, fstream, iomanip, and sstream. If there's something simple I'm overlooking, please let me know.
Well, your program probably isn't passing the statement in the if condition.
Try adding this to test your file is opening correctly:
if(file){
// do all the file inputs
}
else{
std::cerr << "could not open file words.txt" << std::endl;
}
Related
I'm trying to read multiple files in a folder so I can parse through their data.
I first try to fill the list using a text document with all the file names in it, then based on that vector of string, continuously call ifstream so I can read every file and process the word data.
The problem I'm running into is that ifstream is failing to open all of the files, except one in the middle of the list?
Heres the output, its failing to read the dbfiles but they all have the right names?
These files aren't more than 8GB a piece so it should be able to handle it but it's not?
maybe theres a problem with the file paths?
std::ifstream dbfiles(argv[1]);
if (!dbfiles)
{
std::cerr << "Failed to open database " << argv[1] << " for reading." << std::endl;
}
std::string word;
std::vector<std::string> dbfile_names;
std::string file_name;
while (getline(dbfiles, file_name))
{ //reading in the file names
dbfile_names.push_back(file_name);
}//populate list of dbs
dbfiles.close();
for (unsigned int j = 0; j < dbfile_names.size(); j++)
{ //for every single file
std::ifstream dbfile(dbfile_names[j].c_str());
if (!dbfile)
{
std::cout << "Failed to open database file" << dbfile_names[j] << " for reading. READ FAILURE" << std::endl;
}else{
std::cout << "currently reading " << dbfile_names[j] << std::endl;
}
while (dbfile >> word)
{
//do stuff with the segments of data
//here I gather the data word by word and process it
}
dbfile.close();
}
I went into my debugger and found that due to getline, all the file names had a /r at the back of them.
The post over here Getting std :: ifstream to handle LF, CR, and CRLF?, helped describe the problem and how to easily fix it.
My files are now reading accordingly
I am attempting to read from a .csv file in c++. After calling myfile.open(file), is_open returns true, but getline is only returning empty strings.
I have attempted using vectors to read the lines and then writing the vector data to a variable to read, but that has also returned only empty strings.
std::ifstream csvFile;
std::string line = "!", temp= "...";
csvFile.open("file.csv");
if(csvFile.is_open()) {
std::cout << "open\n";
std::cout << line << "\n";
if(getline(csvFile, line)) {
std:: cout << line << "\n";
} else {
std::cout << temp << "\n";
}
}
else {
std:: cout << "not opening\n";
}
std:: cout << line;
My output is as follows after running.
[ctest] open
[ctest] !
[ctest] ...
[ctest]
As shown, the getline() return only an empty string, although the file itself is not empty.
These are the first 20 or so lines of the csv file, and I have made sure that the file is in the current working directory.
Alpha002
16:55:54 13/6/2019
428,1.61,-1.31,-0.13,0,0
448,1.61,-1.47,-0.13,0,0
468,1.68,-1.07,-0.44,0,0
488,1.61,-1.39,-0.76,0,0
508,1.61,-1.47,-0.68,0,0
3528,1.61,-1.55,-0.36,0,0
3548,1.61,-1.31,-0.28,0,0
3568,1.68,-1.15,-0.36,0,0
3588,1.68,-1.63,-0.76,0,0
3608,1.68,-0.76,-0.68,0,0
3628,1.68,-1.15,-0.21,0,0
3648,1.68,-0.76,-0.28,0,0
3668,1.68,-1.39,-0.13,0,0
3688,1.68,-1.07,-0.21,0,0
3708,1.61,-1.47,0.03,0,0
I am not sure how to proceed from here, as i cannot find any issues apart from that, any advice is appreciated!
I found the issue, something is wrong with the file itself I was using. I tried reading from another file using the same methods, and it worked without issues. Thank you to everyone who commented trying to help!
I wrote a code in C++ that writes a .txt file.
Then I want to open the code again and give some information, so I can get a new text depending on what I gave as an input.
For example I want to give the name of a month, and print in another .txt file all the lines that came after the word "November".
I found some solutions, but none of them worked for me!
One solution that I found on stack overflow is the following:
void Keyword(ifstream & stream, string token) {
string line;
while (getline(stream, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
}
}
cout << token << " not found" << endl;
}
I can't print the next lines with the code above.
Any suggestion would be helpful!
Thanks!
If you want to perform operations on files such as 'Read' and/or 'Write',you might want to search on the net(or if you have a C++ book) on topics such as "File I/O operations using C++". Anyways moving on, C++ has 2 basic classes to handle files which are ifstream and ofstream. And to use them you have to include ethier the header fstream(i.e #include<fstream>) or include them separately as #include<ifstream> and #include<ofstream>. ifstream is basically used for all input operations such as reading files etc. Similarly ofstream is used for all output operations such as writing data to files.
You can open a file and write data to it by doing the following,
ofstream myFile("filename");// Create an instance of ofstream and open file for writing data
and to write data to the file use the << operator like below,
myFile<<data;
Similarly, You can open a file and read data as follows,
ifstream myFile("filename");//Create an instance of ifstream and open file to read data
and to read data from the file use the >> operator as shown below,
myFile>>data;
You can also open a file using the method void open(const char *filename, ios::openmode mode); as shown below,
//Writing only
ofstream outFile;
outFile.open("filename.txt",ios::out);
//Reading only
ifstream inFile;
inFile.open("filename.txt",ios::in);
//For reading and writing
fstream file;
file.open("filename.txt",ios::in|ios::out);
//For closing File
outFile.close();
//or
inFile.close();
//or
file.close();
Note the open() method takes various flags such as ios::in for reading mode, ios::out for writing mode, ios::app for adding data to the end etc.
All of these can also combined by using the bit OR operator | as shown below,
outFile.open("filename.txt",ios::out|ios::app);
There is a lot more in IO. I just covered the things required to start.
Here is the solution to your problem. Try to understand it.
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
int main()
{
ofstream outFile;
ifstream inFile;
char fileName[10],data[50];
int noLines;
cout<<"Enter Month:"<<endl;
cin>>fileName;
cout<<"Enter Number of lines you want to enter:"<<endl;
cin>>noLines;
outFile.open(fileName,ios::out);
cout<<fileName<<"(Enter Data):";
for(int i=0;i<=noLines;i++)
{
cin.getline(data,50);
outFile<<data<<endl;
}
outFile.close();
cout<<"Openening "<<fileName<<" :"<<endl;
inFile.open(fileName,ios::in);
for(int i=0 ;i<=noLines ;i++)
{
inFile.getline(data,50);
cout<<data<<endl;
}
inFile.close();
return 0;
}
OP has found most of the solution already:
string line;
while (getline(stream, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
}
}
cout << token << " not found" << endl;
But this only prints the lines with the keyword. And always prints the "not found" message. Ooops.
Instead I pitch:
string line;
bool found = false;
while (!found && getline(stream, line))
{ // search for keyword
if (line.find(token) != string::npos)
{
found = true; // found keyword. Stop looking
}
}
if (found)
{ // print out all remaining lines in the file
while (getline(stream, line))
{
cout << line << endl;
}
}
else
{
cout << token << " not found" << endl;
}
The above splits the finding of the token and the printing of the remaining file into two stages for readability. It can be compressed into one loop, but two things make this a sucker bet:
this program will be IO bound. It will spend the vast majority of its time reading the file, so little tweaks that do not address getting the file into memory are wasted time.
combining the loops would require the addition of logic to the loop that would, over along run, dwarf the minuscule cost of switching loops.
Try this:
http://www.cplusplus.com/doc/tutorial/files/
and this:
http://www.cplusplus.com/forum/beginner/14975/
It's about reading and writing files in c++ and about searching in files.
I am writing a code to check to see if one document (text1.txt) contains a list of banned words (bannedwords.txt) in it.
For example, the text1 document contains lyrics to a song and i want to check whether the word pig from the banned document is included in it. I then want the out put to be similar to:
"pig" found 0 times
"ant" found 3 times
This is what I have come up with so far but cannot seem to put the array of banned words into the search. Any help would be amazing :D
Thanks Fitz
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool CheckWord(char* filename, char* search)
{
int offset;
string line;
ifstream Myfile;
Myfile.open(filename);
if (Myfile.is_open())
{
while (!Myfile.eof())
{
getline(Myfile, line);
if ((offset = line.find(search, 0)) != string::npos)
{
cout << "The Word " << search<< " was found" << endl;
return true;
}
else
{
cout << "Not found";
}
}
Myfile.close();
}
else
cout << "Unable to open this file." << endl;
return false;
}
int main()
{
ifstream file("banned.txt");
if (file.is_open())//file is opened
{
string bannedWords[8];//array is created
for (int i = 0; i < 8; ++i)
{
file >> bannedWords[i];
}
}
else //file could not be opened
{
cout << "File could not be opened." << endl;
}
ifstream text1;//file is opened
text1.open("text1.txt");
if (!text1)//if file could not be opened
{
cout << "Unable to open file" << endl;
}
CheckWord("text1.txt", "cat");
system("pause");
}
Your main() function is reading the contents of banned.txt into an array of 8 std::string named bannedWords.
The array bannedWords is not being used anywhere after that. C++ doesn't work by magic, and compilers are not psychic so cannot read your mind in order to understand what you want your code to do. If an array (or its elements) are not accessed anywhere, they will not be used to do what you want with them.
You need to pass strings from the bannedWords array to CheckWord(). For example;
CheckWord("text1.txt", bannedWords[0].c_str());
will attempt to pass the contents of the first string in bannedWords to CheckWord().
However, that will not compile either unless you make the second parameter of CheckWord() (named search) be const qualified.
Or, better yet, change the type of the second argument to be of type std::string. If you do that, you can eliminate the usage of c_str() in the above.
I don't claim that is a complete solution to your problem - because there are numerous problems in your code, some related to what you've asked about, and some not. However, my advice here will get you started.
Your question is really vague; it looks like you need to spend some time to pin down your program structure before you could ask for help here.
However, since we were all new once, here's a suggestion for a suitable structure:
(I'm leaving out the file handling bits because they're irrelevant to the essential structure)
//Populate your array of banned words
std::string bannedWords[8];
int i;
for (int i = 0; i < 8; ++i)
{
file >> bannedWords[i];
}
//Load the entire file content into memory
std::ifstream in("text1.txt");
std::string fileContents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
So now the entire file content is in the string "fileContents", and the 8 banned words are in "bannedWords". I suggest this approach because otherwise you're opening, reading, and closing the file for every word. Hardly a good design.
Now you've got to check each word against the file content. There's some more sophisticated ways to do this, but your simplest option is a loop.
//Loop through each banned word, and check if it's in the file
for (int i = 0; i < 8; i++)
{
if (fileContents.find(bannedwords[i]) != std::string::npos)
{
//Do whatever
}
}
Obviously you'll need to do the find a little differently if you want to count the number of occurrences, but that's another question.
Basic question I'm hoping theres a way to solve. When I write to a file in my c++ with ofstream it adds a blank line at the end. Is there anyway to stop this behavior? It is causing issues when I load the file the next time the program is run.
int saveScores(scoreboard sBoard, const string filename) {
ofstream outStream;
outStream.open("/Users/Wescat/Desktop/Programming/comp2710/wsc0010_project1/scores.txt");
if (outStream.fail()) {
cout << "Output file opening failed." << endl;
return 1;
}
int i = 0;
while (i < sBoard.numOfScores) {
outStream << sBoard.score->name << endl;
outStream << sBoard.score->score << endl;
sBoard.score = sBoard.score->next;
i++;
}
outStream.close();
return 0;
}
This is perfectly reasonable.
What you're interpreting as a blank line is just the way your text editor represents the presence of a \n character at the end of your actual final line (generated by your final std::endl). It makes sense for that character to be there, as it is as the end of all of your lines. Indeed, this is what "line ending" means!
If this is causing problems when you load the file back in, then I'd suggest that your real bug is in fact there.