简体   繁体   中英

How to go the end of the current line in a file and check the character in c++?

In my project, I have two structs:

struct spell {
    string name;
    string effect;
};

struct spellbook {
    string title;
    string author;
    int pages;
    struct spell* s;
}

The spellbook and spell objects are arrays in this program. I'm reading information from a file and putting it into these two structs. An example of the file is:

2                               //Number of spellbooks
Dark_Secrets Grady 357          //Title author pages
Evil_Force Dark                //Spell name and effect
Grimoire Thompson 1967 
Heavenly_Glow Light
Water_Ray Water

So the spellbook lines end with an integer (page number), while the spell lines end with a letter (The number at the top of the file is taken care of by another method). My plan for distinguishing between them was to check the last char in the line, and seeing if it was a digit. If it was, then I would add it to the spellbook struct. If not, then I would add it to the spell struct. As far as implementing this, I'm not sure how. Here is my add to spellbook struct method: (I have to have 2 different methods for this assignment)

void get_spellbook_data(spellbook* sb, int n, ifstream &file) //Int n is the number of spellbooks {
    char end_line;
    int i = 0;
    //Jump to end of current line. I tried using file,seekg(-1, ios_base::end) but it got me to the end of the file, not the line
    file.get(end_line); //Get last character in the line
    //Jump back to the beginning of the current line
    if (isdigit(end_line)) { //If current line is spellbook
        file >> sb[i].title >> sb[i].author >> sb[i].pages;
           i++;
    }
    else {//If its a spell line
        //Skip this line and advance to the next one
    }
 }
    

That's my current idea so far. The method to add spells would basically be the same as this except checking if the current line does not end with a digit. I feel like there is a better method to get the information, but I'm not exactly sure of how to implement it.

Typical way to read a file line by line:

std::string line;
while (true) {
  if (!std::getline(ifs, line)) {
    // either eof or error, check ifs.eof()
    // need to handle this somehow, leaving this up to you
  }

  // Now you have the whole text line in the line.
  if (!line.empty()) break;

  // the line was empty for some reason, continue to next line, until
  // you get non-empty line, eof or error
}

// Now you have non-empty line. Check that the last char is digit...
if (std::isdigit(line.back()) {
  // the last character is digit
}
// but I'd split line into space separated tokens and check if there is 2 or 3 tokens.

If I were you, I'd read a whole line in at a time, and then determine if I'm looking at a book or a spell line. So the code may look like:

struct spell {
    std::string name;
    std::string effect;
    spell(std::string str) {
        std::istringstream strm(str);
        strm >> name >> effect;
    }
};

struct spellbook {
    std::string title;
    std::string author;
    int pages;
    std::vector<spell> spells; // vector for nicer code and a cleaner name
    spellbook(std::string str) {
        std::istringstream strm(str);
        strm >> title >> author >> pages;
    }
};

bool is_book(std::string str) {
    return isdigit(str.back());
}

int main() {
    std::vector<spellbook> books;
    ifstream fhand("Some/File/Location.txt");
    std::string line;
    while(std::getline(fhand, line)) {
        if(is_book(line)) {
            books.push_back(spellbook(line));
        } else {
            books.back().spells.push_back(spell(line));
        }
    }
}

Here's a live example (using stdin instead of a file): https://ideone.com/s9qk7Y

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM