C++ - Program to count occurrences of word without ifstream - c++

I have a code where the program will read a word from user and then count its total occurrence in a text file “my_data.txt”. But I don't want to use the ifstream function. I already have a text like "the sky is blue".
I want the program to read from that. I know I can create a string and add the text but how can I count the occurrences?
Here is my code so far:
#include<iostream.h>
#include<fstream.h>
#include<string.h>
int main()
{
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;
}

Without using ifstream, you have some choices: cin and piping; or fscanf. I really don't understand why you don't want to use ifstream.
cin and Piping
You can use the cin stream and let the OS rout the data file to your program.
You loop would look something like this:
std::string word;
while (cin >> word)
{
// process the word
}
An example invocation using a command line is:
my_program.exe < my_data.txt
This invocation tells the Operating System to redirect the standard input to a driver that reads from the file my_data.txt.
Using fscanf
The fscanf comes from the C background and can be used to read from files. Developing the correct format specifier for a word can be tricky. But it isn't std::ifstream.
Also, fscanf cannot be safely used with the std::string, whereas std::ifstream can be used safely with std::string.
Edit 1: Words From a String
Since there is some ambiguity in your question, one interpretation is that you want to count words from a string of text.
Let's say you have a declaration like this:
const std::string sentence = "I'm hungry, feed me now.";
You could use std::istringstream and count the words:
std::string word;
std::istringstream sentence_stream(sentence);
unsigned int word_count = 0U;
while (sentence_stream >> word)
{
++word_count;
}

Related

How to take multiple line string input in C++?

I am learning C++. I want to take multiple line string as input but I can't. I am using getline() for it but it is taking only one line input. When I press enter for writing next line it stoped taking input and print the first line.
I want to give input like the example below
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
But it takes only the first line input.
My code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << s << endl;
return 0;
}
Please help me to know how can I do that.
Thank you.
Either you write a loop to read individual lines and concatenate them to a single string, thats what this answer suggests. If you are fine with designating a specific character to signal the end of the input, you can use the getline overload that takes a delimiter as parameter:
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin,s,'x');
std::cout << s;
}
The user would have to type an x to end input, so this input
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
x
would result in this output:
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
Of course this won't work when the string to be entered contains x, which renders the approach rather useless.
However, instead of using a "real" character as delimiter you can use the EOF character (EOF = end of file) like this:
std::getline(std::cin, s, static_cast<char>(EOF));
Then input is terminated by whatever your terminal interprets as EOF, eg Ctrl-d in linux.
Thanks to #darcamo for enlightening me on the EOF part.
You can only read one line at a time with std::getline if you don’t provide your own delimiter. If you want to accumulate multiple lines, one at a time, you need a place to put the result. Define a second string. Read a line at a time into s with std::getline, and then append s to the result string. Like this:
std::string result;
std::string s;
while (std::getline(std::cin, s))
result += s;
You can take several lines using the code below if you know how many lines you will input.
int line=3, t;
string s, bigString;
for(int i=0 ; i<line ; i++)
{
getline(cin,s); // This is to input the sentence
bigString += s + "\n";
}
cout << bigString;
If you don't know how many lines you will input (Input from file until end of file) then you can check this.
string s;
vector<string> all;
while(getline(cin,s))
{
all.push_back(s);// This is to input the sentence
}
for(auto i:all)
{
cout << i << endl;
}

calculating average length of words in a local text file

I need to find the
- average length of all the words
- the shortest and longest word length; and
- how many words are
in a separate text file, using c++. There are 79 words in the file and it is called "test.txt."
what i have so far is
#include <bits/stdc++.h>
#include <cstdio>
using namespace std;
int main()
{
FILE* fp;
char buffer[100];
fp = fopen("test.txt", "r");
while (!feof(fp)) // to read file
{
// fucntion used to read the contents of file
fread(buffer, sizeof(buffer), 100, fp);
cout << buffer;
}
return 0;
}
All this does is print out the words that are in the file.
I am using an online compiler until i can get to my desktop with visual studio 2017 later today
Well, with c++ instead of FILE* rather use a std::ifstream, a std::string word; variable and formatted text extraction operator>>() to read single words from the file in a loop:
std::ifstream infile("test.txt");
std:string word;
while(infile >> word) {
}
Count every word read from the file in a variable int wordCount;
int wordCount = 0;
while(infile >> word) {
++wordCount;
}
Sum up the character lengths of the read words in another variable int totalWordsCharacters; (you can use the std::string::length() function to determine the number of characters used in a word).
int totalWordsCharacters = 0;
while(infile >> word) {
totalWordsCharacters += word.length();
}
After you completed reading that file, you can easily compute the average length of words by dividing
int avgCharacterPerWord = totalWordsCharacters / wordCount;
Here's a complete working example, the only difference is the '\n' in your input file format was replaced by a simple blank character (' ').
If you want to have the average between ALL the words, you have to add all lengths together and divide it by the number of words in your file (You said 79 words)
But if you want to get the average between only the shortest word and the longest one you will have to first: Get those words.
You can do that by simply use two counters as you go through all words. The first counter will be set to the length of the current word if it has a smaller length as the first counter. The second counter will be set to the length of the current word if it has a grater length as the second counter.
Then you will add those two counters together and divide them by 2.
Your problem is that you are writing C Code. This makes the problem harder.
In C++ reading a list of words from a file is simple using the >> operator.
std::ifstream file("FileName");
std::string word;
while(file >> word)
{
// I have read another word from the file.
// Do your calculations here.
}
// print out your results here after the loop.
Note the >> operator treats end of line just like a space and simply ignores it (It acts like a word separator).

Reading in from a txt file. Trouble parsing info

I want to read in scores from a txt file. The scores are going into a struct.
struct playerScore
{
char name[32];
int score, difficulty;
float time;
};
the text file looks like this
Seth 26.255 40 7
as one line, where each item is followed by a tab. (Name\t time\t score\t difficulty\n)
When I begin to read in the text, I don't know how to tell the program when to stop. The scores file could be any number of lines or score entries. This is what I have attempted.
hs.open("scores.txt", ios_base::in);
hs.seekg(0, hs.beg);
if (hs.is_open())
{
int currpos = 0;
while (int(hs.tellg()) != int(hs.end));
{
hs>> inScore.name;
hs >> inScore.time;
hs >> inScore.score;
hs >> inScore.difficulty;
hs.ignore(INT_MAX, '\n');
AllScores.push_back(inScore);
currpos = (int)hs.tellg();
}
}
I'm trying to make a loop that will read in a line of code into a temp struct for the data, then push that struct into a vector of structs. Then update the currpos variable with the current location of the input pointer. However, the loop just gets stuck on the condition and freezes.
There are a multitude of ways to do this, but the following is likely what you're looking for. Declare a free-operator for extracting a single-line definition of a player-score:
std::istream& operator >>(std::istream& inf, playerScore& ps)
{
// read a single line.
std::string line;
if (std::getline(inf, line))
{
// use a string stream to parse line by line.
std::istringstream iss(line);
if (!(iss.getline(ps.name, sizeof(ps.name)/sizeof(*ps.name), '\t') &&
(iss >> ps.time >> ps.score >> ps.difficulty)))
{
// fails to parse a full record. set the top-stream fail-bit.
inf.setstate(std::ios::failbit);
}
}
return inf;
}
With that, your read code can now do this:
std::istream_iterator<playerScore> hs_it(hs), hs_eof;
std::vector<playerScore> scores(hs_it, hs_eof);
I dont think that you can just >> from your file. Do you think it will take everything till \t? :)
You can try to take for example token with strtok()
I guess it can use '\t' to split string and take for each variable via this function needed part of string
In case if it strtok() doesnt work that way i guess you can just copy till '\t' in sub-loop
You can do like this
playerScore s1;
fstream file;
file.open("scores.txt", ios::in | ios::out);
while(!file.eof()) //For end of while loop
{
file.read(s1, sizeof(playerScore));//read data in one structure.
AllScores.push_back(s1);
}

Using C++ ifstream extraction operator>> to read formatted data from a file

As my learning, I am trying to use c++ ifstream and its operator>> to read data from a text file using code below. The text file outdummy.txt has following contents:
just dummy
Hello ofstream
555
My questions is how to read char data present in the file into a char array or string. How to do this using the ifstream::operator>> in code below.
#include <iostream>
#include <fstream>
int main()
{
int a;
string s;
char buf[100];
ifstream in("outdummy.txt",ios_base::in);
in.operator>>(a); //How to read integer? How to read the string data.??
cout << a;
in.close();
getchar();
return 0;
}
If you want to use formatted input, you have to know in advance what data to expect and read it into variables of the according data type. For example, if you know that the number is always the fifth token, as in your example, you could do this:
std::string s1, s2, s3, s4;
int n;
std::ifstream in("outdummy.txt");
if (in >> s1 >> s2 >> s3 >> s4 >> n)
{
std::cout << "We read the number " << n << std::endl;
}
On the other hand, if you know that the number is always on the third line, by itself:
std::string line;
std::getline(in, line); // have line 1
std::getline(in, line); // have line 2
std::getline(in, line); // have line 3
std::istringstream iss(line);
if (iss >> n)
{
std::cout << "We read the number " << n << std::endl;
}
As you can see, to read a token as a string, you just stream it into a std::string. It's important to remember that the formatted input operator works token by token, and tokens are separated by whitespace (spaces, tabs, newlines). The usual fundamental choice to make is whether you process a file entirely in tokens (first version), or line by line (second version). For line-by-line processing, you use getline first to read one line into a string, and then use a string stream to tokenize the string.
A word about validation: You cannot know whether a formatted extraction will actually succeed, because that depends on the input data. Therefore, you should always check whether an input operation succeeded, and abort parsing if it doesn't, because in case of a failure your variables won't contain the correct data, but you have no way of knowing that later. So always say it like this:
if (in >> v) { /* ... */ } // v is some suitable variable
else { /* could not read into v */ }
if (std::getline(in, line)) { /* process line */ }
else { /* error, no line! */ }
The latter construction is usually used in a while loop, to read an entire file line by line:
while (std::getline(in, line)) { /* process line */ }
ifstream has ios_base::in by default. You don't need to specify it.
operator>> can be invoked directly as an operator: in >> a.
Reading strings is the same: in >> s, but the caveat is that it is whitespace-delimited, so it will read "just" by itself, without "dummy".
If you want to read complete lines, use std::getline(in, s).
Since you have elected to use C-strings, you can use the getline method of your ifstream object (not std::getline() which works with std::strings), which will allow you to specify the C-string and a maximum size for the buffer.
Based on what you had, and adding an additional buffer for the second line:
char buf[100];
char buf2[100];
in.getline(buf,sizeof(buf));
in.getline(buf2,sizeof(buf2));
in >> a;
However, as the other poster has proposed, try using the std::string and its methods, it will make your life easier.
You can read file contents and use a Finite State Machine for parsing.
Example:
void Parse(const char* buffer, size_t length);
size_t GetBufferSize();
size_t bufferSize = GetBufferSize();
char* buffer = new char[bufferSize];
std::ifstream in("input.txt");
while(in.getline(buffer, bufferSize)) {
Parse(buffer, in.gcount());
}
Alternatively, you can use a tool like Flex to write your parser.

C++ file input problem

Hi Guys! I have the following code:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
#define MAXN 301
string names[MAXN];
vector<string> names_vec;
int main(int argc, char **argv)
{
ifstream fin(argv[1]);
int n;
fin>>n;
string line;
while(getline(fin, line))
names_vec.push_back(line);
for(int i=0; i<names_vec.size(); i++)
cout<<names_vec[i]<<endl;
return 0;
}
and names.in file for input:
5
CLEOpatra
AISHWARYA rai
jOHn f. KeNNeDy
leonardo DA Vinci
tyleR durdeN
When i compile it and run it first prints empty line, that names_vec[0] is empty line. Can anyone explain why and how can I fix it?
The problem is that you're mixing the >> operator with calls to getline. Generally, you want to use one or the other, but not both of them together.
The reason you get an empty string in your vector is because >> will NOT consume the whitespace which causes it to stop. That is, it reads the "5", finds the newline character after it, and then stops, leaving the newline character in the ifstream.
Then, the call to getline encounters the newline character and immediately says, "Done! I read a line!". It consumes the newline character and returns the entire string leading up to it -- which in this case was the empty string.
If you know that your data will be formatted properly (no invalid input), it might be easiest just to use >> to read the entire file. Otherwise, I would recommend using getline to read each line one at a time, then using a stringstream object to parse the data out of the line.
EDIT
I just noticed that the rest of your input has first/last names separated by spaces. Since >> stops on spaces, it would probably be easiest to use getline to read the entire file. Example of reading the 5:
string line;
getline(fin, line);
stringstream converter;
converter << line;
int n;
converter >> n;