input data- read word by word

First of all sorry for my bad english... I will try to make not so many mistakes:D

Ok i need to write a programs that reads some text from a file and then it outputs the statistics of the words. So i have already completed that the programs says how many charecters there are in a text. Now i would like you to help me with something.

I want to do a function that reads the text from file and than output it like this:

read text : Today is very warm.

text output when i run programe:
Today
is
very
warm

So i think i need to read this text from some file than put it in array and then output it with for sentence.

ifstream entrance;
char word;

entrance.open("lala.txt");
while (!entrance.eof())
{
.........
.........

}
entrance.close();


for(i=0; i.....)
cout<<word[i]<<endl;

But i dont know how to do this...

So can you pls help me.

Thank you all!
somehow like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
char string[256];
//read file into string

int pos=0;
char* word=string;
while(pos<256 && string[pos]!=0) {
 if(string[pos]==' ') {
  string[pos]=0;
  std::cout<<word<<std::endl;
  word=string+pos;
 }
 pos+=sizeof(char);
}
std::cout<<word<<std::endl;
Last edited on
i do this inside or where?

ifstream entrance;

entrance.open("lala.txt");
while (!entrance.eof())
{
.........
.........

}
entrance.close();

And how do i tell that the text that is inside a file is stored in string?
The good old c++ way!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <string>
#include <vector>
#include <fstream>
#include <iostream>

int main()
{
  std::vector <std::string> words; // Vector to hold our words we read in.
  std::string str; // Temp string to
  std::cout << "Read from a file!" << std::endl;

  std::ifstream fin("thisfile.txt"); // Open it up!
  while (fin >> str) // Will read up to eof() and stop at every
  {                  // whitespace it hits. (like spaces!)
    words.push_back(str);
  }
  fin.close(); // Close that file!

  for (int i = 0; i < words.size(); ++i)
    std::cout << words.at(i) << std::endl; // Print so I can see this all worked!

  return 0;
}
Can i change this line how std::vector <std::string> words;?

Couse we havent done anything with vectors, so is it any other posibility to write this ?
You could use an regular array with strings... I suppose.
thisfile wrote:
THIS IS A TEST HERE
HOLD 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
#include <string>
#include <fstream>
#include <iostream>

int main()
{
  const int SIZE = 10;
  std::string words[SIZE]; // C array? to hold our words we read in.
  std::string str; // Temp string to
  std::cout << "Read from a file!" << std::endl;

  std::ifstream fin("thisfile.txt");
  for (int i = 0; (fin >> str) && (i < SIZE); ++i) // Will read up to eof() and stop at every
  {                                                // whitespace it hits. (like spaces!)
    std::cout << "This string is: " << str << std::endl;
    words[i] = str;
  } // We now also need to stop before we hit the no define array space.
  fin.close();

  std::cout << std::endl;
  for (int i = 0; i < SIZE; ++i)
    std::cout << words[i] << std::endl;

  return 0;
}
Read from a file!
This string is: THIS
This string is: IS
This string is: A
This string is: TEST
This string is: HERE
This string is: HOLD
This string is: ON

THIS
IS
A
TEST
HERE
HOLD
ON
yea this code work like a charm, exept for 1 thing :D

If i change constant of size, to bigger value... like 500. Than when i run a program the words are written like they should be, but there is a big blank spot... And i need to scrol a long way down to get to "press any key to continue". So the programe doest stops when there are no more words to output but it still outputs.... :D
Use a std::vector instead of an array. It doesn't make sense to use an array when you don't know how many elements you're going to read in.
If you don't know the size of the data you read in use a vector. Thats all I can say. My array solution expects small input.
Ok so vector is just like array, but you dont need to know the size of data?
It dynamically makes itself larger and has a method to remember its size for you.
Look at: http://www.cplusplus.com/reference/stl/vector/
Ok so let me sum up that code with vector. So it reads file and stores data in vector string.

that ifstream fin(lala.txt) is just like entrance.open("lala.txt")?

What exactly does this mean fin >>str ?

And what in above code has the same meaning as while (!entrance.eof())?

So i would like to thanks in advance for all your help... I will try to work something with this code, and if i wont know how to do additional stuff i will ask you guys again :D

Again thank you for your time and help :P
that ifstream fin(lala.txt) is just like entrance.open("lala.txt")?

Yes. If you pass a string as argument to the constructor it will open the file for you. You can also let it go out of scope and the destructor will close it for you.

What exactly does this mean fin >>str ?

It's a call to the extraction operator. Same as std::cin >> foo; only you're getting input from a file stream rather than directly from the user.

And what in above code has the same meaning as while (!entrance.eof())?

When used as a boolean value, the expression fin >> str will evaluate to false if the stream goes into fail(), bad() or eof() states.
Yes. fin is the name of the ifstream variable just like entrance. There is a constructor overload that opens a file immediately. So you can do these:

1
2
3
4
std::ifstream entrance("lala.txt"); // SAME AS

std::ifstream entrance;
entrance.open("lala.txt");


fin >> str is just like cin >> from iostream.
The difference here is that fin >> str will read up to a whitespace and stop and in a loop that reads every word in. The reason it works like !entrance.eof() is because entrance.eof() checks to see if the badbit or eof flag is set (its part of streams and is hard to explain here, you'll learn it later) and if it is, it returns true, otherwise false. Now fin >> has the same check. Once it reads the eof or a badbit flag is on it stops reading.

The code you have would be the same as mine if you did this as well:
1
2
3
4
5
6
7
8
9
10
while (!entrance.eof())
{
   entrance >> str; // This reads every character up to the first whitespace (tab, space, newline)
   // and inside this loop it will go until the eof() check is true.
}

while (entrance >> str)
{
   // Same thing as above, now just waits for entrance >> to read the eof character or get its badbit flag set. Reads every word, ignores whitespace.
}
filipe wrote:
When used as a boolean value, the expression fin >> str will evaluate to false if the stream goes into fail(), bad() or eof() states.
wolfgang wrote:
The difference here is that fin >> str will read up to a whitespace and stop and in a loop that reads every word in. The reason it works like !entrance.eof() is because entrance.eof() checks to see if the badbit or eof flag is set

I though so too, until a week ago or so, when this post surfaced: http://www.cplusplus.com/forum/general/34292/

It appears that the results from operator! and operator void* depend only on the value of the failbit and badbit, but not on the value of eof. The expression fin >> str is therefore not strictly stronger condition compared to the expression !entrance.eof(). Now I see, that the idiom while (fin >> str) { ... } actually works not because the condition fails immediately when the end of the stream is reached (; if that was the case the last word would escape from the body of the loop), but because the condition fails when the stream was exhausted and fin has no more characters to pass to str, which results in a failbit.

Thinking further in this direction, using the while (!fin.eof()) { fin >> str; ... } approach may be generally incorrect. It may work for extracting strings, but it could be incorrect for say, char-s. According to some sources (see **), the eof bit is set when you try to read something past the end of the file, not when you read the last character before the end of the file. So, if the previous extraction reached the end of the file, without reading past it, the !fin.eof() condition will still evaluate to true, but the following extraction in the next loop iteration will be unsuccessful, because there is nothing left to read, and there will be erroneous extra processing of non-extent input. I'm not sure on this. Any confirmation?

** Random picks:
http://cpp.comsci.us/etymology/include/iostream/eof.html
http://stackoverflow.com/questions/292740/c-reading-from-a-file-blocks-any-further-writing-why
Ok i have worked something with the code, but i took that one with arreys and not that one with vectors. Now i have problem, because i have code which tells how many times is some word repeating in the text. And if i have the size of an array 10 and only 7 words in file, it prints 3 empty spaces so he reaches the size 10. I also dunno how do sort the words by size using vectors(i did this by using arrays). So can someone pls rewrite my code from array to vectors but in very simple way so i will understand it pls :D

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
void frequency(string words[WW])
{
  
   
  string str; // Temp string to
  int counter7 = 0;
  

  ifstream fin("lalala.txt");
  for (int i = 0; (fin >> str) && (i < WW); ++i) 
  {                                               
    
    words[i] = str;
  } 
  fin.close();

  cout <<endl;
  for (int i = 0; i < WW; ++i)
  {
      counter7=0;
      for (int j = 0; j < WW; j++)
      {
   if (words[j] == words[i]) 
   counter7++;

      }
      cout<<words[i]<<":"<<counter7<<endl;
      
   }
   

   
}



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
void size(string words[WW])
{
  
   
  string str; // Temp string to
  

  ifstream fin("lalala.txt");
  for (int i = 0; (fin >> str) && (i < WW); ++i) 
  {                                                
    
    words[i] = str;
  } 
  fin.close();

  cout <<endl;
  for (int i = 0; i < WW; ++i)
  {
      for (int j = 0; j < WW; j++)
      {
   if (words[j].length() < words[i].length()) 
            {
                 string a = words[i]; 
                 words[i] = words[j];
                 words[j] = a;
                 
            }
            
   }
   }
   for (int i = 0; i < WW; ++i)
   cout << words[i] <<endl;
   
}
Ok i think i rewrite those 2 codes with vectors.... But i have some problem in second code, so can you take a look pls

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
40
41
#include <string>
#include <vector>
#include <fstream>
#include <iostream>

int main()
{
   
  std::vector <std::string> words; // Vector to hold our words we read in.
  std::string str; // Temp string to
  std::cout << "Read from a file!" << std::endl;
  

  std::ifstream fin("lala.txt"); // Open it up!
  while (fin >> str) // Will read up to eof() and stop at every
  {                  // whitespace it hits. (like spaces!)
    words.push_back(str);
  }
  fin.close(); // Close that file!

  
  for (int i = 0; i < words.size(); ++i)
  {
      for (int j = 0; j < words.size(); j++)
      {
       if (words[j].length() < words[i].length()) 
            {
                 string a = words[i]; 
                 words[i] = words[j];
                 words[j] = a;
                 
            }
            
   }
   }
   for (int i = 0; i < words.size(); ++i)
   cout << words[i] <<endl;
   
   system("pause");
  return 0;
}


i have this errors

string undeclared
expected `;' before "a"
`a' undeclared (first use this function)
`cout' undeclared (first use this function)
`endl' undeclared (first use this function)
You didn't specify the namespace. You need to specify it like this:

std::string a = words[i]; in line 28

std::cout << words[i] << std::endl; in line 37.

Or instead of typing std:: all over the place, you can use (the using directive):
using namespace std;

Insert it after the include directives and it will apply to all of the following function definitions. Like this:
1
2
3
4
5
6
7
8
#include <string>
#include <vector>
#include <fstream>
#include <iostream>

using namespace std;

int main()

Insert it at the beginning of a function (like main() in this case) and it will apply to the body of the function. Like this:
1
2
3
4
int main()
{
   
    using namespace std;

Then you will not need to prepend std:: anymore.

Regards

PS: how can I escape the array indexes, so that they are not treated as a tag?
Last edited on
Topic archived. No new replies allowed.