简体   繁体   中英

How to static cast 2D vector size() (size_t to int) in C++?

I have not found any other posts which answer this question. This is a c++ program. I am receiving an error at the line:

int entryval = static_cast<int>(database[0].size());

The error says: Thread 1: EXC_BAD_ACCESS (code = 1, address = 0x8) it directs my attention to a size() file within a vector file, to the line:

{return static_cast<size_type>(this->__end_ - this->__begin_);}

Am I formatting the type conversion incorrectly?

//Species ID,Kingdom,Phylum,Class,Order,Family,Genus,Species,Authority,Infraspecific rank,Infraspecific name,Infraspecific authority,Stock/subpopulation,Synonyms,Common names (Eng),Common names (Fre),Common names (Spa),Red List status,Red List criteria,Red List criteria version,Year assessed,Population trend,Petitioned
//2055,ANIMALIA,CHORDATA,MAMMALIA,CARNIVORA,OTARIIDAE,Arctocephalus,australis,"(Zimmermann, 1783)",,,,,Arctophoca australis,South American Fur Seal,Otarie  fourrure Australe,Oso Marino Austral,LC,,3.1,2016,increasing,N
//41664,ANIMALIA,CHORDATA,MAMMALIA,CARNIVORA,OTARIIDAE,Arctocephalus,forsteri,"(Lesson, 1828)",,,,,Arctocephalus australis subspecies forsteri|Arctophoca australis subspecies forsteri,"New Zealand Fur Seal, Antipodean Fur Seal, Australasian Fur Seal, Black Fur Seal, Long-nosed Fur Seal, South Australian Fur Seal",,,LC,,3.1,2015,increasing,N

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{

std::string entry;
std::vector<std::vector<std::string> > database;
std::ifstream file("C:/Users/mewtwo/Desktop/Programs/Seals.csv");

if (file) {
    while (std::getline(file, entry)) {
        size_t dbsize = database.size();
        database.resize(dbsize + 1);
        std::istringstream ss(entry);
        std::string field, push_field("");
        bool no_quotes = true;

        while (std::getline(ss, field, ',')) {
            if (static_cast<size_t>(std::count(field.begin(), field.end(), '"')) % 2 != 0) {
                no_quotes = !no_quotes;
                field.erase(remove(field.begin(), field.end(), '\"'), field.end());
            }

            push_field += field + (no_quotes ? "" : ",");

            if (no_quotes) {
                database[dbsize].push_back(push_field);
                push_field.resize(0);
            }
        }
    }
}

int dbval =  static_cast<int>(database.size());
int entryval = static_cast<int>(database[0].size());
int animalChoice;
int dataChoice;
int switchChoice;
bool moreData;
bool moreAnimal = true;
while (moreAnimal == true) {

    std::cout << "*********************ENDANGERED ANIMALS*********************" << std::endl;
    std::cout << "Choose an animal! (1-" << dbval - 1 << ")" << std::endl;
    for (int x = 1; x < database.size(); x++) {
        if (database[x][14] != ""){
            std::cout << x << ". " << database[x][14] << std::endl;
        }
        else {
            std::cout << x << ". " << database[x][6] << " " << database[x][7] << std::endl;
        }

    }
    std::cout << "\nAnimal choice:";
    while (!(std::cin >> animalChoice) || animalChoice <= 0 || animalChoice >= dbval ){
        std::cout << "\nYou pressed an incorrect key. Try again1." << std::endl;
        std::cin.clear();
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "\nAnimal choice:";
    }
    moreData = true;
    while (moreData == true) {
        std::cout << "\nWhat data do you want to access about the ";
        if(database[animalChoice][14] != ""){
            std::cout << database[animalChoice][14] << std::endl;
        }
        else{
            std::cout << database[animalChoice][6] << " " << database[animalChoice][7] << std::endl;
        }
        std::cout << "?" << std::endl;
        for (int x = 0; x < entryval; x++) {
            std::cout << x + 1 << "." << database[0][x] << std::endl;
        }
        std::cout << "\nData choice:";
        while (!(std::cin >> dataChoice) || dataChoice <= 0 || dataChoice >= entryval ){
            std::cout << "You pressed an incorrect key. Try again2." << std::endl;
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "\nData choice:";
        }
        std::cout << database[animalChoice][14] << std::endl;
        std::cout << database[0][dataChoice - 1] << ": " << database[animalChoice][dataChoice - 1] << std::endl;
        std::cout << "\nWould you like to access more data about the " << database[animalChoice][14];
        if(database[animalChoice][14] != ""){
            std::cout << database[animalChoice][14] << std::endl;
        }
        else{
            std::cout << database[animalChoice][6] << " " << database[animalChoice][7] << std::endl;
        }
        std::cout << "?" << std::endl;
        std::cout << "1. Yes" << std::endl;
        std::cout << "2. Access data of a different animal" << std::endl;
        std::cout << "3. Quit" << std::endl;
        std::cout << "\nChoice:";
        while (!(std::cin >> switchChoice) || switchChoice <= 0 || switchChoice >= 4 ){
            std::cout << "You pressed an incorrect key. Try again3." << std::endl;
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "\nChoice:";
        }
        if (switchChoice == 1) {
            moreData = true;
        }
        else if (switchChoice == 2) {
            moreData = false;
            break;
        }
        else if (switchChoice == 3) {
            exit(1);
        }
        else {
            std::cout << "\nPROGRAM FAILURE" << std::endl;
            exit(1);
        }
    }
}
return 0;
}

Also, are there any other obvious problems with my code? The code takes the whole species database of IUCN and presents the data using menus.

The low value in address = 0x8 hints that the code tried to access a member through a null pointer, which comes from an invalid "null" reference returned by database[0] .

The only way operator[] would return such a broken reference is if the access was out of bounds, triggering undefined behaviour. In this case, it looks like your std::vector implementation just blindly indexes through its data pointer, which is null when the vector is empty.

Bottom line: nothing was ever inserted into your vector. This is probably caused by an error while reading your file. You should add error checking to your code and report them cleanly.

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