error Поток 1: EXC_BAD_ACCESS (код = 1, адрес = 0x0):
Это происходит из-за вашего определения reverseVector по двум причинам: во-первых, string temp = 0;
, где вы инициализируете свою строку с char*
, равным NULL с неопределенным поведением, просто используйте string temp;
, второе - на первом l oop, когда i 0 означает доступ к names[names.size()]
, так что после последнего элемента. Из-за этого ваш алгоритм некорректен с более чем 3 элементами в векторе, потому что вы всегда обмениваетесь с name[0]
. Вы должны обменяться name[0]
с именами [names.size () - 1] and
name 1 with names[names.size()-2]
et c, go вернется к этой функции в конце моего ответ
учитель написал функцию сортировки выбора, поэтому я не изменил ее
поэтому скажите вашему учителю, что его функция предполагает, что вектор не пуст, и когда он тест пуст:
for (startScan = 0; startScan < (arr.size() - 1); startScan++)
всегда ложно arr.size()
возвращает size_t
, равное без знака , поэтому при пустом значения ~ 0u, что самое большое возможное значение size_t
.
Скажите, что он смешивает (подписано) int и (без знака) size_t
неверно и обычно сигнализируется компилятором, и мы в C ++, а не в C, они имеют итераторов .
О main
Чтобы избежать ошибки в selectionSort проверьте, что вектор не пуст, прежде чем вызывать его, поэтому:
if (! boyNames.empty())
selectionSort(boyNames);
if (! girlNames.empty())
selectionSort(girlNames);
У вас есть специальный случай N в getName , когда вход имя N вы не должны учитывать ввод:
if (boyName != "N") {
boyNameFound = search(boyName, boyNames);
displayResult("boy's", boyName, boyNameFound);
}
if (girlName != "N") {
girlNameFound = search(girlName, girlNames);
displayResult("girl's", girlName, girlNameFound);
}
Примечание основной сделать два раза одно и то же, один раз для мальчика и один раз для девушка, добавить функцию позволяет не дублировать весь код.
Но, кажется, main тоже написано вашим учителем, как жаль на самом деле.
In getVector может быть, вы можете создать сообщение, когда вы не можете прочитать файл. Чтобы помочь чтению кода, я рекомендую вам добавлять пустую строку после каждого объявления частей, конструктор ifstream позволяет открыть файл, чтобы вы могли иметь
vector<string> getVector(const string& fileName)
{
string name;
ifstream file(fileName);
vector<string> namesFromFile;
while(getline(file, name))
{
namesFromFile.push_back(name);
}
return namesFromFile;
}
или
vector<string> getVector(const string& fileName)
{
vector<string> namesFromFile;
ifstream file(fileName);
if (! file)
cerr << "cannot read " << fileName << endl;
else
{
string name;
while(getline(file, name))
{
namesFromFile.push_back(name);
}
}
return namesFromFile;
}
О getName
Он не управляет регистром EOF, а также если имя не пустое или содержит только пробелы или пробелы в начале и / или конце.
Если имя должно быть уникальным словом, поэтому «Джон» не «Джон Доу», вы можете заменить использование getline на cin >> nameChoice;
и заставить N , если EOF:
string getName(const string& gender)
{
string nameChoice;
cout << "Enter a " << gender << " name, or N if you do not wish to enter a " << gender << " name: " << endl;
return (!(cin >> nameChoice)) ? string("N") : nameChoice;
}
Если имя может быть составлено, после вызова необходимо удалить пробелы в начале и конце, а затем проверить, является ли введенное имя пустое в силу N :
string getName(const string& gender)
{
string nameChoice;
cout << "Enter a " << gender << " name, or N if you do not wish to enter a " << gender << " name: " << endl;
getline(cin, nameChoice);
size_t b = 0;
for (;;) {
if (b == nameChoice.size())
return "N";
if (!std::isspace(nameChoice[b]))
break;
b += 1;
}
size_t e = nameChoice.size();
while ((e != 0) && std::isspace(nameChoice[--e]))
;
return (e >= b) ? nameChoice.substr(b, e - b + 1) : string("N");
}
Поскольку в коде учителя нет итератора , я не буду использовать их здесь и позже. Заметьте, может быть, вам также придется удалить лишние пробелы в составленном имени, чтобы заменить «Джон Доу» на «Джон Доу»?
О search
векторы имен сортируются благодаря вызову selectionSort , поэтому поиск во всем векторе бесполезен, если имя меньше, чем имя в векторе
bool search(const string& nameChoice, const vector<string>& names)
{
for(size_t i = 0; i < names.size(); i++)
{
if(nameChoice == names[i])
{
return true;
}
if (nameChoice < names[i])
{
return false;
}
}
return false;
}
в любом случае, даже при такой небольшой оптимизации ваш поиск все еще находится в O (N)
Вы также можете иметь более эффективный поиск в O (log (N)) сравнивая с половиной (под) векторов, делая это самостоятельно или используя std :: binary_search :
About displayResult
nameFound это true из false это не может быть что-то еще, поэтому вы не можете достичь else if(names == "N")
, вам нужно сначала проверить этот случай, и бесполезно проверять if(!nameFound)
, когда вы знаете, что if(nameFound)
равно ложно , например (например, name вместо names потому что есть только одно имя):
void displayResult(const string& gender, const string& name, bool nameFound)// change this function so either displays name found not found or chose //not to enter
{
if(name == "N")
cout << "You choose to not enter a " << gender << " name." << endl;
else if(nameFound)
cout << name << " is one of the most popular " << gender << "names." << endl;
else
cout << name << " is NOT one of the most popular " << gender << " names." << endl;
}
или
void displayResult(const string& gender, const string& name, bool nameFound)// change this function so either displays name found not found or chose //not to enter
{
if(name == "N")
cout << "You choose to not enter a ";
else
cout << name << " is" << ((nameFound) ? "" : " NOT")
<< " one of the most popular ";
cout << gender << " name." << endl;
}
О writeToFile
Как и для ifstream Конструктор ofstream позволяет открыть файл
Вы не проверяете, можете ли вы записать в файл, это опасно, потому что скрыть Проблема, лучше сделать, например:
void writeToFile(const string& fileName, const vector<string>& names)
{
ofstream outputFile(fileName);
if (! outputFile)
cerr << "Cannot open " << fileName << " to write it" << endl;
else
{
for(size_t i = 0; i < names.size(); i++)
outputFile << names[i] << endl;
}
}
О reverseVector
Как я уже сказал, его определение не правильно, он коротким путем должен использовать std :: reverse , остальное делать самостоятельно:
void reverseVector(vector<string>& names)
{
string temp;
size_t pos = 0, sup = names.size();
while ((pos + 1) < sup)
{
temp = names[pos];
names[pos++] = names[--sup];
names[sup] = temp;
}
for (auto s : names) cout << s << ' ';
cout << endl;
}