Count one certain string in a file in C++ - c++

This is my code.
I am supposed to count the number of 'duck' in a txt file and print string like "There were 2 ducks in animals01.txt"
Now I get no error and nothing return.
Please tell me what's wrong?
#include <iostream> // for printf()
#include <cstdlib> // for exit(), perror()
#include <fstream> // for ifstream
using namespace std;
int main(int argc, char *argv[])
{
if (argc!=2) {
// if argc is not 2, print an error message and exit
cerr << "Usage: "<< argv[0] << " inputFile" << endl;
exit(1); // defined in cstdlib
}
return 0;
int num = 0;
ifstream ifs;
ifs.open(argv[1]);
string line;
do{
getline(ifs, line);
cout<<line<<endl;
if(line == "duck"){num++;}
}while(!ifs.eof());
cout<<"There were"<<num<<"ducks in"<<argv[1]<< endl;
}

You have the line return 0; before you actually did anything, and when you return main() the program is terminated.
By the way, don't use while(!ifs.eof()) because the eof flag only gets set at the first attempt to read past the end of the file, not when you read exactly to the end of the file due to a line break at the end. Do something like this. Also, fix your indenting as it is very misleading.

Read the file word by word.
Example:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string str, strToSearch = "ducks";
int wordCount = 0;
ifstream fin("thisfile.txt");
while (fin >> str) // Will read up to eof() and stop at every whitespace it hits. (like spaces!)
{
if(str==strToSearch)
wordCount++;
}
fin.close();
cout<<"There were"<<wordCount<<"ducks in thisfile.txt"<<endl;
return 0;
}

Related

I'm stuck on how to read from a text file

/* In the text file I have a char followed by a blankspace then a string. I'm trying to read the char and string into seperated arrays. Any help is appreciated */
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
char arrivOrDepart;
string licensePlt;
ifstream inFile;
inFile.open("Text.txt");
if (!inFile)
{
cout << "Can't open file" << endl;
return 1;
}
for (int i = 0; i < 4; i++)
{
getline(cin, arrivOrDepart[i]);
getline(cin, licensePlt[i]);
}
inFile.close();
cin.get();
return 0;
}
//text file
A QWE123
A ASD123
A ZXC123
A WER123
A SDF123
#include <fstream>
#include <iterator>
#include <vector>
this reads from file into vector
std::ifstream input("d:\\testinput.txt");
std::vector<std::string> bytes(
(std::istreambuf_iterator<std::string>(input)),
(std::istreambuf_iterator<std::string>()));
input.close();
then, just put the data into whatever container you want. you should almost always prefer vector over array btw
There are a few problems with the code:
getline is the wrong tool of choice for this. if you want to split a stream based on spaces, use >>.
arrivOrDepart and licensePlt are not defined as arrays but are used as arrays.
reading from cin, not from file.
My suggested fixes (excluding using vectors instead of arrays):
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std; // avoid using this
int main()
{
const int MAXARRAY = 4; // avoid using magic numbers
char arrivOrDepart[MAXARRAY]; // made an array, but prefer std::vector
string licensePlt[MAXARRAY]; //made an array
ifstream inFile;
inFile.open("Text.txt");
if (!inFile)
{
cout << "Can't open file" << endl;
return 1;
}
string temp;
int i = 0;
while (i < MAXARRAY && // not overrunning the arrays
inFile >> temp >> licensePlt[i] && // read data from file stream
temp.length() == 1) // read only one character for arrivOrDepart
{
arrivOrDepart = temp[0];
i++;
}
inFile.close();
cin.get();
return 0;
}
Recommended reading:
Why is "using namespace std" considered bad practice?
What is a magic number, and why is it bad?
std::vector documentation (Alternate easier to read but often less accurate documentation)
std::getline documentation. Note the third parameter used to set the parsing delimiter.

Text file not reading c++ MacOSX

I have an issue with some code I have been working on. I am trying to read the contents of a text file (input.txt) into a variable fileContents. The loop in the code enters, but the program produces no output. Some of the variables are not used, I know about this. What is wrong?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
ifstream input("input.txt");
ofstream output("output.txt"); //init output controller
// new lines will be skipped unless we stop it from happening:
//input.unsetf(std::ios_base::skipws);
// count the newlines with an algorithm specialized for counting:
unsigned line_count = std::count(std::istream_iterator<char>(input),std::istream_iterator<char>(), '\n');
string fileContents = ""; //init message, that will be filled by input.txt
string str; //temp string
while (input >> fileContents)
{
//cout << "loop entered";
cout << fileContents << "\n";
}
//cout << "test" << "\n";
return 0;
}

C++ Script to count number of pattern occurrence

I have this code that counts the number of pattern occurrence in textfile.
#include <iostream>
int main()
{
// std::cout << "Hello World!" << std::endl;
// return 0;
ifstream fin("my_data.txt"); //opening text file
int count=0;
char ch[20],c[20];
cout<<"Enter a word to count:";
gets(c);
while(fin)
{
fin>>ch;
if(strcmp(ch,c)==0)
count++;
}
cout<<"Occurrence="<<count<<"n";
fin.close(); //closing file
return 0;
}
However, upon testing I got this error
10 2 C:\Users\80977432\Documents\C++\Untitled1.cpp [Error] 'ifstream' was not declared in this scope
ifstream cout strcmp , etc all belongs to namespace std.
So use std::ifstream, std::cout , etc
Also use #include <fstream> for file I/O operation
#include<cstring> for std::strcmp

Beginning Address Endless Loop

I'm trying to get the beginning address of each line of my file as I read it, and print it out to the screen, but for some reason it just results in an endless loop. The file i'm reading is just a normal text file. Here's what I have going right now.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char* argv){
ifstream file;
string name, lnstr;
int addy;
if (argc > 1)
name = argv[1];
else
{
cout << "Please Enter Your Filename: ";
getline(cin, name);
}
file.open(name.data());
if(!file)
{
perror(name.data());
exit(1);
}
addy = 0;
while(getline(file, lnstr))
{
cout << file.seekg(addy, ios::beg) << endl;
addy++;
}
}
Even if I put 0 as the first parameter of seekg, it still results in an endless loop, or it just shows the same number a bunch of times. Not sure what i'm missing.
When you call ios::beg you set the position of the get pointer to the beginning of the file. You don't actually need this call and this code should work for you:
file.open(name.c_str()); // open file
if(file) {
while(getline(file, lnstr)) {
cout<< lnstr <<endl;
}
}
More on seekg.
I think you want tellg, not seekg.

Argument checking

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char* argv[])
{
string STRING;
ifstream infile;
STRING = argv[1];
infile.open(argv[1]);
if (infile.fail())// covers a miss spelling of a fail name
{
cout << "ERROR. Did you make a mistake in the Spelling of the File\n";
return 1;
}
else
{
while(!infile.eof())
{
getline(infile,STRING); // Get the line
cout<<STRING + "\n"; // Prints out File line
}
infile.close();
return 0;
}
}
I have got this program working fine apart from one problem
if the user only runs the program with no file name (what I believe to be called arguments) e.g ./displayfile then I get a Segmentation fault
How would I amend my code so that the program would exit with an error message along the lines of "Add a file name"
My first thought is something along the lines of
if (!argc=2)
{
cout << "ERROR. Enter a file name";
return 1;
}
ADDED:
just in case this matters am compiling using
g++ displayfile.cpp -o displayfile
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char* argv[]) {
if(argc != 2) {
cout << "You need to supply one argument to this program.";
return -1;
}
string STRING;
ifstream infile;
STRING = argv[1];
infile.open(argv[1]);
if (infile.fail())// covers a miss spelling of a fail name {
cout << "ERROR. Did you make a mistake in the Spelling of the File\n";
return 1;
}
else {
while(!infile.eof()) {
getline(infile,STRING); // Get the line
cout<<STRING + "\n"; // Prints out File line
}
infile.close();
return 0;
}
}
Besides the obvious check for argc != 2 I couldn't help fixing some of the worse code and the obvious error:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char* argv[])
{
if (argc != 2)
{
cout << "ERROR. Invalid number of arguments\n";
return 1;
}
ifstream infile(argv[1]);
if (!infile) // covers a miss spelling of a fail name
{
cout << "ERROR. Did you make a mistake in the Spelling of the File\n";
return 1;
}
string STRING;
while(getline(infile, STRING))
cout << STRING << '\n'; // Prints out file line
return 0;
}
You don't need to call ifstream::open, just use the constructor, likewise don't you need to declare STRING so early and neither to initialize it to the file name, since you don't use it. Don't forget, this is not C, you don't need a whole mess of declarations at the beginning of each function.
Second, checking for the flags of a stream is often a bad idea, just check for !infile to find any errors. But the real error is in checking for infile.eof in the while condition, since it only gets set once getline has tryed to read over the end of the file, so you would actually print one (probably empty) line too much. Just check for getline's return value to find any errors or the end of file.
And don't add the newline onto the string when outputting, just put it out after the string. And last but not least, no need for infile.close, since the destructor calls it anyway.
change STRING = argv[1]; to if (argv[1] != null) STRING = argv[1]; not sure though, so you'll have to test it out first.