Find word in a textfile

I found an exercise on the internet and decided to give a try.
The exercise is this:
"Write a modular program in C++ that search in a file strings with the presence of a word previously given by input, counting how many times the word has been found in the file as you wrote it.

Example:
Input
Path: C:/etc/etc/file.txt
Word: apple
Output
The word has been found (numbers of words found) times."

This is the code I wrote:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

int main()
{
	int countwords=0;
	string path;
	string line;
	string word;
	cout<<"Write the path of the file."<<endl;
	cin>>path;
	ifstream File(path);
	if(File.is_open())
	{
		while(getline(File,line))
		{
			cout<<line<<endl;
		}
		
		cout<<"Write the word you're searching for."<<endl;
		cin>>word;
		while(!File.eof())
		{
			if(word.compare(line)==0)
				countwords++;
		}
		cout<<"The word has been found "<<countwords<<" times."<<endl;
		File.close();
	}
	else
	{
		cout<<"Error! File not found!";
		exit(1);
	}
}


The first error I found is in "ifstream File(path)" and I don't get what is wrong there. If I write directly "file.txt" it gives me no error. Why?
The second error is when I start the program and he doesn't count the number of times the word has been found. What's the problem there? It's like he jump the "while".
I know it has to be a modular program but for now I want to try it without functions.
Can someone help me?
You never opened your file you are trying to read from. Your if statement is saying while it is open, not open.

File.open(path);
Last edited on
AbsoluTe88 wrote:
You never opened your file you are trying to read from.

Incorrect.

Kernul wrote:
The first error I found is in "ifstream File(path)" and I don't get what is wrong there.

Try ifstream File(path.c_str()) or enable C++11 support in your tool chain to use as-is.
cire wrote:
Incorrect.


I am not saying you are wrong by any means, I am confused now though. I made a test file and was not able to open a file without using File.open(path). It might not have contributed to his error like I thought, but you still need to open the file somewhere don't you?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main()
{
	string path;
	ifstream inFile(path);

	cout << "Enter path of file: ";
	cin >> path;

	inFile.open(path);
	
	if(inFile.is_open())
	{
		cout << "Found file\n";
	}
	else
	{
		cout << "Could not find file\n";
	}

	inFile.close();

	system("PAUSE");
	return 0;
}


Example:

1
2
3
4
5
With .open();

Enter path of file: fileOne.txt
Found file
Press any key to continue . . .


1
2
3
4
5
Without .open();

Enter path of file: fileOne.txt
Could not find file
Press any key to continue . . .

Last edited on
AbsoluTe88 wrote:
I am not saying you are wrong by any means, I am confused now though. I made a test file and was not able to open a file without using File.open(path).


Feeding the path to the constructor is the same as not feeding the path to the constructor and then feeding the path to the open method.

Your code is faulty. In line 9 you feed inFile's constructor an empty string as the path, then you ask the user for the name of the path. You would not use the constructor invoked on line 9 with the open method invoked on line 14.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main()
{
	string path;

	cout << "Enter path of file: ";
	cin >> path;

	ifstream inFile(path); // note that this occurs after the path is supplied.

	// inFile.open(path); 
	
	if(inFile.is_open())
	{
		cout << "Found file\n";
	}
	else
	{
		cout << "Could not find file\n";
	}

	// inFile.close();   // destructor closes the file, this is unnecessary.

	system("PAUSE");
	return 0;
}
Thank you very much for clarifying. I will try to stay off of topics that I don't fully understand :)
Okay, sorry but I've been a lot busy these days.
cire, I tried ifstream file(path.c_str()) and worked, thanks!
However one problem still remain. The word I search.
When I write the word I'm searching for the program blocks and I can't write anymore(it doesn't crash, it just blocks with the underline).
1
2
3
4
5
6
Write the path of the file.
file.txt
File found.
Write the word you're searching for.
apple
_ 

Why? I don't understand what is the problem.
You will need to post the code that causes this, one can only guess what your problem is without it.

EDIT: Also if you're not on Windows or DOS system("PAUSE") will not work and may well hang your program.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

int main()
{
	int countwords=0;
	string path, line, word;
	cout<<"Write the path of the file."<<endl;
	cin>>path;
	ifstream File(path.c_str());
	if(File.is_open())
	{
		cout<<"File found."<<endl;
		line=File.get();
		cout<<"Write the word you're searching for."<<endl;
		cin>>word;
		while(!File.eof())
		{
			if(word.compare(line)==0)
				countwords++;
		}
		cout<<"The word has been found "<<countwords<<" times."<<endl;
		File.close();
	}
	else
	{
		cout<<"Error! File not found!";
		exit(1);
	}
}

This is the code.
Last edited on
In the while loop you are just continuously comparing two strings without changing them.

You probably want to set line to the next string from File each loop.
Yes. But line=File.get() doesn't solve the problem?
That is performed once, above. You need to stick it at the end of the while loop as well or you're not extracting from the file any more (and the condition !File.eof() never changes).
@ Absolute 88: Don't do that either, I get corrected on what feels like a daily bases on this site. This is how we correct misunderstandings.

@ OP: Using "std::istream.get()" without parameters only extracts one character at a time and the set_equal operator overwrites, it does not append. You want one of the overloads that takes the char_type and stream size as parameters if you are hoping to compare the data you are reading to anything more then a single character: http://www.cplusplus.com/reference/istream/basic_istream/get/
So, what do I have to write in char_type and stream size? Do I have to write a new char variable like this?
1
2
3
4
5
#define N 256
...
char buff[N];
...
line=File.get(buff, N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <fstream>
#include <string>

int main()
{
        std::cout  << "Write the path of the file\n" ;
	std::string path ;
	std::cin >> path ;

	std::ifstream file( path.c_str() ) ;

	if( file.is_open() )
	{
		std::cout << "File '" << path << "' opened.\n" ;

		std::cout << "Write the word you're searching for\n" ;
		std::string word ;
		std::cin >> word ;

		int countwords = 0 ;
		std::string candidate ;
		while( file >> candidate ) // for each candidate word read from the file 
		{
			if( word == candidate ) ++countwords ;
		}

		std::cout << "The word '" << word << "' has been found " << countwords << " times.\n" ;
	}

	else
	{
		std::cerr << "Error! File not found!\n" ;
		return 1 ;
	}
}

http://coliru.stacked-crooked.com/a/e55cd34bf20296e8
Oh wow! Why if you write "file>>candidate" as the condition it works? What does that while do?
file >> candidate attempts to read characters into the string. If no characters could be read, input fails, and the stream is put into a failed state. The result of file >> candidate is a reference to the input stream.

while( file >> candidate )

while after file >> candidate, the stream is not in a failed state

while attempted input did not fail

while( !( file >> candidate ).fail() )

while( ( ( file >> candidate ) , !file.fail() ) )

http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool
Last edited on
Oh great! Thank you! Now I understand! :D
Topic archived. No new replies allowed.