Okay, I'm trying to do my homework, but my code isn't doing what I want it to. What I'm trying to do is have the user enter a file name and then the program will output the number of words in the file. It works fine the first time through the loop, but when prompted again, the file never opens correctly. Here is my code:

#include <iostream>
#include <fstream>
#include <cassert>

using namespace std;

int main()
{
    int      numberOfWords;
    string   fileName;
    string   wordString;
    ifstream infile;

    cout << "File to process (type quit to exit): ";
    cin  >> fileName;

    while(fileName != "quit")
    {
        infile.open(fileName.c_str());

        assert(infile);

        infile >> wordString;

        for(numberOfWords = 0; infile; numberOfWords++)
        {
            infile >> wordString;
        }

        infile.close();

        cout << fileName << " has " << numberOfWords
             << " words." << endl << endl;

        cout << "File to process (type quit to exit): ";
        cin  >> fileName;
    }
}

I have six different files that all work the first time through the loop. I've tried re-ordering the loop stuff, but nothing seems to work. I then tried infile.close() but that didn't do anything. Please don't write the code for me... maybe a suggestion on what to do would be best. I really like this class. This is the first time I've run into something I cannot fix myself.
Thanks.

I tried inFile.clear(), too but that also did nothing to help my problem.

DISREGUARD, You are using iostream and I'm not sure how that works with strings.

You can't compare strings the way you do.

while (strcmp (filename, "quit") != 0)

I think that should solve your problem.

what do you mean by "You can't compare strings the way you do."? I enter the loop just fine. I also got a couple errors when I tried replacing my code with yours. BTW, I haven't learned about comparing strings yet... I gues I have to figure out a different way.

>You can't compare strings the way you do.
Sure you can. The string class overloads the relational operators. Though <string> needs to be included.

>the file never opens correctly
Try this:

#include <iostream>
#include <fstream>
#include <cassert>
#include <string>

using namespace std;

int main()
{
  int numberOfWords;
  string fileName;
  string wordString;

  cout << "File to process (type quit to exit): ";
  cin >> fileName;

  while(fileName != "quit")
  {
    ifstream infile(fileName.c_str());

    assert(infile);

    infile >> wordString;

    for(numberOfWords = 0; infile; numberOfWords++)
    {
      infile >> wordString;
    }

    cout << fileName << " has " << numberOfWords
      << " words." << endl << endl;

    cout << "File to process (type quit to exit): ";
    cin >> fileName;
  }
}

>assert(infile);
No. assert is designed as a debugging tool, not as a run-time error handling mechanism. Failure to open a file is not considered a programming error, it's an input error in this case. So you should be using a conditional statement:

if (!in) {
  cerr<<"Failure to open file"<<endl;
  // Terminate here or handle the error
}

I know it's subtle, but a program error and a programming error are two completely different things and need to be dealt with in different ways.

I treid putting #include <string> but it didn't change anything. The assert thing comes from my teacher. He wanted us to use that instead of an if statement. Don't ask me why. I think an if statement is more clear during the run time phase of a program, though an assert statement may look cleaner in the actual code. Any more suggestions?

>He wanted us to use that instead of an if statement.
Tell him I said he's a bad teacher.

>Any more suggestions?
...Well, if you bothered to read the code I gave you, you'll find that I changed more than just adding "#include <string>". :rolleyes: Try running the code.

yeah, sorry about that... I'm stressing out about this program. I'm running it right now...

This is waht I get when I run the code:

Error : Undefined symbol: 'std::basic_ifstream<char, struct std::char_traits<char> >::basic_ifstream<char, struct std::char_traits<char> >(unsigned int, char const *, enum std::ios_base::openmode) (??0?$basic_ifstream@DU?$char_traits@D@std@@@std@@QAE@IPBDW1openmode@ios_base@1@@Z)'
referenced from '_main' in main.cpp:19
main.cpp line 19

Yes, the exact code... I'm creating another project to see if I messed something up by adding another .cpp file. I'm using CodeWarrior.

I did something wrong the last time I ran the code, this time it worked perfectly. Thank you so much for helping... I'm still looking for the differences in our code... My brain is pretty fried right now and I can't see them. Thank you again, though. It works perfectly.

I see I see... instead of using the infile.open(fileName.c_str()) you used ifstream infile(fileName.c_str()). Is that all?

>Is that all?
Well, I could have rewritten it entirely:

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

bool getfile(string& file)
{
  cout<<"Enter a file to open: ";
  return cin>> file ? file != "quit" : false; // w00t!
}

int main()
{
  string file;

  while (getfile(file)) {
    ifstream in(file.c_str());

    if (!in) {
      cerr<<"Error opening file"<<endl;
      return EXIT_FAILURE;
    }

    string word;
    int n = 0;

    while (in>> word)
      ++n;

    cout<< file <<" has "<< n <<" words"<<endl;
  }

  return EXIT_SUCCESS;
}

But why do more than you have to? ;)

Okay, since I haven't learned about using ifstream infile(fileName.c_str()) yet, I finally got my program to work like this:
code:

#include <iostream>
#include <fstream>
#include <cassert>

using namespace std;

int main()
{
    int numberOfWords;
    string fileName;
    string wordString;
    ifstream infile;
  
    cout << "File to process (type quit to exit): ";
    cin >> fileName;

    while(fileName != "quit")
    {
        infile.open(fileName.c_str());

        assert(infile);

        infile >> wordString;

        for(numberOfWords = 0; infile; numberOfWords++)
        {
            infile >> wordString;
        }

        infile.close(); // forgot to include these two functions
        infile.clear(); // in my code the first time around... oops

        cout << fileName << " has " << numberOfWords
             << " words." << endl << endl;

        cout << "File to process (type quit to exit): ";
        cin >> fileName;
    }
}

Your code is probably a lot better than mine. I have only been in class for about a month and a half. anyway... why are my code tags not working on the board??? Oh yeah, I din't mean to belittle your work by saying "is that all?"... I was actually just making sure I hadn't missed anything and partially making fun of myself. Anyway, thank you so much for your help. It's much appreciated.

>why are my code tags not working on the board???
It looks as if you aren't using a closing tag. Do this (without the spaces):
[ code ]
// Code goes here
[ /code ]

>I din't mean to belittle your work by saying "is that all?"
No worries, I didn't see it as belittling. Often it's a simple and subtle change that's the difference between broken code and working code.

I am using the closing tag.. I swear.
[code]this is code between the tags[/close]
I thought it was weird that the second one would dissapear... Hold on now... The code seems to be working. It wasn't last time I was lookinf at the board, but now all my code looks like it should... unless somebody came in and edited my posts. Anyway, Narue: Thank you for all your help. You can probably expect I'll be back.

weird, now it's working on the older ones but not on the new one. I don't get it. I swear I have been doing the same thing the whole time. whatever though. It doesn't really matter.

This article has been dead for over six months. Start a new discussion instead.