1
\$\begingroup\$

I'm not sure if I should ask here. The program worked it's just that I'm not satisfied how I implemented it because I used two while loop to read a specific data and I have no idea what am I doing. How can I make it more efficient and instead of using two while loop?

spritesheet.txt

spritesheet.txt

int main() {

fstream file("spritesheet.txt");

int x, y, width, height;
string num1, num2;
string line;
string data;

if (file.is_open())
{
    while (getline(file, line))
    {
        if (line == "enemy")
        {
            while (file >> data >> num1 >> num2)
            {
                if (data == "xy:")
                {
                    x = std::stoi(num1);
                    y = std::stoi(num2);
                    cout << "x: " << x << endl << "y: " << y << endl;
                }
                if (data == "size:")
                {
                    width = std::stoi(num1);
                    height = std::stoi(num2);
                    cout << "width: " << width << endl << "height: " << height << endl;
                }
            }
            file.close();
            break;
        }
    }
}
system("pause");

}

\$\endgroup\$
  • 1
    \$\begingroup\$ Also, avoid using namespace std; \$\endgroup\$ – Yk Cheese May 27 '17 at 13:25
2
\$\begingroup\$

You could add state to the reader: e.g. have a std::string variable target outside of the loop, read the lines in a while loop and...

while (getline(file, line)) {
  if (line=="enemy" || line=="player") {
    target=line; // remember where to put things
  }
  else {
    const std::string::size_type p=line.find(":");
    if (p!=std::string::npos) {
      assert(!target.empty());
      const std::string tag=line.substr(0, p);
      const std::string val=line.substr(p+1);

      // parse val (maybe with istringstream),
      // then put values into appropriate destination,
      // by using target and tag
    }
  }
}
\$\endgroup\$
  • \$\begingroup\$ Would it be a good idea to add an errorcheck to the loop header? I.e. while (file && getline(file, line)) ? \$\endgroup\$ – yuri May 27 '17 at 12:58
  • \$\begingroup\$ You certainly could do that... if one is aware this would be using operator bool() of stream, which reflects failbit || badbit (file is an fstream instance, and not a C FILE* which is tested against zero). But in my view, that's ok only if "just stopping with reading the file" would be the wanted program behavior. A different approach would be to throwan exception, thus forcing some caller to react to something unexpected. If for example reading incomplete, truncated files would pose any danger, one should go for the exception approach (and add an "end marker" to the file). \$\endgroup\$ – jvb May 27 '17 at 16:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.