Password program - c++

#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
#include <iomanip>
#include <cctype>
using namespace std;
int main()
{
fstream fin;
string password;
cout << "Please enter your password!" << endl;
cin >> password;
fin.open("Text.txt");
int nlen = password.length();
if (nlen <= 7)
return false;
if (nlen >= 8)
return true;
bool hasUpp = false;
bool hasLow = false;
bool hasDig = false;
bool hasSym = false;
for (int i = 0; i < nlen; i++)
{
if (isupper(password[i]))
hasUpp = true;
if (islower(password[i]))
hasLow = true;
if (isdigit(password[i]))
hasDig = true;
}
if (hasLow && hasUpp && hasDig && hasSym)
{
return true;
}
else
{
return false;
}
if (hasLow && hasUpp && hasDig && hasSym)
{
cout << "Your password is strong! " << endl;
}
else
{
cout << "Your password is too weak! " << endl;
}
cin.get();
cin.get();
return 0;
}
This program is supposed to take input data from a user and decide whether or not it is a somewhat strong password. I realize this is not near finished yet. The problem I am having is making the program read my input file and figure out whether or not any of the words in the input file are being entered as passwords, which would then tell them their password is bad.

I've made some modifications to your program to make it work at least with user input data. You propably wondered why you don't get any output from your program? There are two if-clauses within your program which will cause the main() function to return (= your application terminates):
if (nlen <= 7)
return false;
if (nlen >= 8)
return true;
One of the return statements is called since one of the if-clauses is always true and therefore your program will exit there.
Here is the modified code to process a single password entered by the user:
#include <iostream>
#include <string>
#include <fstream>
#include <cmath>
#include <iomanip>
#include <cctype>
using namespace std;
int main()
{
string password;
cout << "Please enter your password!" << endl;
cin >> password;
int nlen = password.length();
bool hasUpp = false;
bool hasLow = false;
bool hasDig = false;
bool hasSym = false;
bool isLong = false;
if (nlen >= 8)
isLong = false;
for (int i = 0; i < nlen; i++)
{
if (isupper(password[i]))
hasUpp = true;
if (islower(password[i]))
hasLow = true;
if (isdigit(password[i]))
hasDig = true;
}
if (hasLow && hasUpp && hasDig && hasSym && isLong)
{
cout << "Your password is strong! " << endl;
}
else
{
cout << "Your password is too weak! " << endl;
}
cin.get();
cin.get();
return 0;
}
To extend this to read several passwords from a file, you have to read the file line by line (as explained here) and process each line.

**YOU CAN DO LIKE THIS**
#include <iostream>
#include <conio.h>
#include <windows.h>
using namespace std;
void gotox(int x)
{
COORD xy = {0, 0};
xy.X = x;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), xy);
}
void getx(int &x) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
if(GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
x = csbi.dwCursorPosition.X;
}
}
int main()
{
SetConsoleTitle("file password protector");
char pas;
string password = "";
int x,t = 0;
cout<<"enter password : ";
do
{
pas = _getch();
switch(int(pas))
{
case 8: getx(x);
if(x>17)
{
--x;
gotox(x);
cout<<" ";
if(password.length()>0){password.erase(password.length()-1,1);}
--t;
gotox(x);
}
break;
case 27: return 0;
case 13: if(t>8)
{
pass = 27
}
break;
default :if(t < 30)
{
if(int(pas)>0)
{
password.push_back(pas);cout<<"*";++t;
}
else
{
pas = _getch();
}
}}}while(pas != 13);
bool hasUpp = false;
bool hasLow = false;
bool hasDig = false;
bool hasSym = false;
for (int i = 0; i < t; i++)
{
if (isupper(password[i]))
hasUpp = true;
if (islower(password[i]))
hasLow = true;
if (isdigit(password[i]))
hasDig = true;
}
if (hasLow && hasUpp && hasDig && hasSym)
{
cout << "Your password is strong! " << endl;
}
else
{
cout << "Your password is too weak! " << endl;
}
_getch();
return 0;
}

Related

GetAsyncKeyState Toggling

I'm trying to make a very basic 'switch' that will toggle by pressing the HOME key. I've come up with a solution that will display "Off." or "On." in console depending on whether "bool homeKeyWasDown" is true or false. So, I have technically achieved my goal, however I'm uncertain if it is very efficient. Is there some other means that I'm missing here?
#include <iostream>
#include <windows.h>
#pragma comment(lib, "user32.lib")
#include <stdlib.h>
using namespace std;
int main()
{
SHORT homeKey;
bool homeKeyWasDown = false;
homeKey = GetAsyncKeyState(VK_HOME);
while (homeKeyWasDown == false) {
homeKey = GetAsyncKeyState(VK_HOME);
cout << "Off.";
Sleep(100);
system("CLS");
while (homeKey != 0) {
homeKey = GetAsyncKeyState(VK_HOME);
homeKeyWasDown = true;
Sleep(100);
}
while (homeKeyWasDown == true) {
homeKey = GetAsyncKeyState(VK_HOME);
cout << "On.";
Sleep(100);
system("CLS");
while (homeKey != 0) {
homeKey = GetAsyncKeyState(VK_HOME);
homeKeyWasDown = false;
Sleep(100);
}
}
}
}

Program execution not stopping at scanf() after first read

I want that at every iteration of the do-while() loop the program stops at the scanf() function, but the program loops the same amount of times as the number of white spaces that the read string contains before stoping again at the scanf()
enum Comando
{
AYUDA,
LOGIN,
LOGOUT,
LISTAR_BUSES,
LISTAR_RUTAS,
LISTAR_VIAJES,
NULL_COMMAND
};
//Funcion que registra el comando ingresado por el usuario para indicarle al programa que es lo que debe hacer
pair<Comando, queue<char*>> ProcesarComando(char comandoEntero[20]);
void MostrarAyuda();
int main()
{
bool salir = false;
char comando[20];
Comando cmd;
do
{
printf("\n\t$ ");
scanf(" %s", comando);
cmd = ProcesarComando(comando).first;
switch(cmd)
{
case AYUDA:
break;
case LOGIN:
break;
case LOGOUT:
break;
case LISTAR_BUSES:
break;
case LISTAR_RUTAS:
break;
case LISTAR_VIAJES:
break;
case NULL_COMMAND:
break;
}
}
while(!salir);
//system("pause");
return 0;
}
pair<Comando, queue<char*>> ProcesarComando(char comandoEntero[20])
{
int pos = 0;
char *argumento, *comandoNombre;
bool tieneParametros = false;
pair<Comando, queue<char*>> retorno;
argumento = new char[20];
while(comandoEntero[pos] != '\0')
{
if(comandoEntero[pos] == '<'|| comandoEntero[pos] == '[')
{
tieneParametros = true;
}
else if(tieneParametros && comandoEntero[pos] != ' ' && comandoEntero[pos] != '<' && comandoEntero[pos] != '>' && comandoEntero[pos] != '[' && comandoEntero[pos] != ']')
{
strncat(argumento, &comandoEntero[pos], 1);
}
else if(tieneParametros && comandoEntero[pos] == ' ')
{
cout<<"HOLAAAAAAA";
retorno.second.push(argumento);
memset(argumento, '\0', strlen(argumento));
tieneParametros = false;
}
pos++;
}
comandoNombre = new char[20];
comandoNombre = strtok(comandoEntero, " ");
if(strcmp(comandoNombre, "ayuda") == 0)
{
retorno.first = AYUDA;
return retorno;
}
else if(strcmp(comandoNombre, "login") == 0)
{
retorno.first = LOGIN;
return retorno;
}
else if(strcmp(comandoNombre, "logout") == 0)
{
retorno.first = LOGOUT;
return retorno;
}
else if(strcmp(comandoNombre, "listar_buses") == 0)
{
retorno.first = LISTAR_BUSES;
return retorno;
}
else if(strcmp(comandoNombre, "listar_rutas") == 0)
{
retorno.first = LISTAR_RUTAS;
return retorno;
}
else if(strcmp(comandoNombre, "listar_viajes") == 0)
{
retorno.first = LISTAR_VIAJES;
return retorno;
}
// printf("\n%s", retorno.second.front());
// retorno.second.pop();
// printf("\n%s", retorno.second.front());
retorno.first = NULL_COMMAND;
return retorno;
}
So, because the program is not stoping at the scanf(), it is printing all those money signs but without letting me interact with the program until the amount of the string white spaces are reached...
I know that it may be something dumb, but couldn't figure it out, hope that you guys could help me.THANKS :v
Here I am posting a proper C++ implementation of your code. I know that code-only answers are not recommended. But here, I don't have much to tell you. You need to yourself check about the things you lack knowledge about. Better search things on this site.
#include <algorithm>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
enum Comando {
AYUDA,
LOGIN,
LOGOUT,
LISTAR_BUSES,
LISTAR_RUTAS,
LISTAR_VIAJES,
NULL_COMMAND
};
auto ProcesarComando(std::string comandoEntero) {
std::string argumento, comandoNombre;
bool tieneParametros = false;
std::queue<std::string> retorno;
for (auto &&i : comandoEntero)
if (i == '<' or i == '[')
tieneParametros = true;
else if (tieneParametros and std::string(" []<>").find(i) == size_t(-1))
argumento.push_back(i);
else if (tieneParametros and i == ' ') {
std::cout << "HOLAAAAAAA\n";
retorno.push(argumento);
argumento.clear();
tieneParametros = false;
}
std::stringstream(comandoEntero) >> comandoNombre;
const std::vector<std::string> cmd = {"ayuda", "login",
"logout", "listar_buses",
"listar_rutas", "listar_viajes"};
return std::make_pair(
static_cast<Comando>(std::find(cmd.begin(), cmd.end(), comandoNombre) -
cmd.begin()),
retorno);
}
int main() {
do {
std::cout << "\n$ ";
std::string comando;
std::getline(std::cin, comando);
switch (ProcesarComando(comando).first) {
case AYUDA:
break;
case LOGIN:
break;
case LOGOUT:
break;
case LISTAR_BUSES:
break;
case LISTAR_RUTAS:
break;
case LISTAR_VIAJES:
break;
default: // case NULL_COMMAND:
}
} while (true);
}

Error in Xcode: Thread 1: EXC_BAD_ACCESS (code=1, address=0xe8)

This is supposed to be a c++ game which works by reading in files. How ever, I am not really sure what is the problem in the code below. When I enter the file name it gives me this error (code is below, problematic line is also shown). If you can't fix it can you at least tell me why this seems to work fine in another computer, but when I try to compile in Xcode it goes wrong?
#include "AdvRoom.h"
AdvRoom::AdvRoom()
{
}
bool AdvRoom::readRoom(ifstream &roomFile)
{
bool success = true;
char data[64];
int pointer;
while ((roomFile.get(data[0])) && data[0] == '\n') {}
roomFile.unget();
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64);
this->number = atoi(data);
roomFile.get(data[0]);
}
else success = false;
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64);
this->name = data;
roomFile.get(data[0]);
}
else success = false;
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64);
while (data[0] != '-' && success) {
this->description.push_back(data);
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data[0]);
roomFile.get(data, 64);
}
else success = false;
}
roomFile.get(data[0]);
}
else success = false;
if (success && !roomFile.eof() && roomFile.good()) {
// Check for \n
string direction;
int destination = 0;
string key;
while (roomFile.peek() != '\n' && success) {
if (success && !roomFile.eof() && roomFile.good()) {
roomFile.get(data, 64, ' ');
direction = data;
while ((roomFile.get(data[0])) && data[0] == ' ') {}
roomFile.unget();
int i = 0;
while ((roomFile.get(data[i])) && data[i] != '\n' && data[i] != ' ') {
++i;
}
if (data[i] == ' ') {
data[i] = '\0';
destination = atoi(data);
roomFile.get(data, 64, '\n');
key = data;
roomFile.get(data[0]);
}
else if (data[i] == '\n') {
data[i] = '\0';
destination = atoi(data);
key = "";
//roomFile.get(data[0]);
}
AdvMotionTableEntry entry(direction, destination, key);
this->motionTable.push_back(entry);
}
else success = false;
}
}
else success = false;
return success;
}
vector<string> AdvRoom::getDescription()
{
vector<string> copyDesc = this->description;
return copyDesc;
}
string AdvRoom::getName()
{
string copyName = this->name;
return copyName;
}
void AdvRoom::addObject(AdvObject obj)
{
// This function should add the obj to the room.
// It however, should not add the object to the room
// if the room already contains the object.
this->objects.push_back(obj);
}
AdvObject AdvRoom::removeObject(string objName)
{
AdvObject deletedObj;
// This function should remove the object with objName.
for (int i = 0; i < this->objects.size(); ++i) {
if (this->objects[i].getName() == objName) {
deletedObj = this->objects[i];
this->objects.erase(this->objects.begin() + i);
}
}
return deletedObj;
}
bool AdvRoom::containsObject(string objName)
{
// Returns true if object with objName is in the room.
bool success = false;
for (int i = 0; i < this->objects.size(); ++i) {
if (this->objects[i].getName() == objName) {
success = true;
}
}
return success;
}
int AdvRoom::objectCount()
{
return this->objects.size();
}
AdvObject AdvRoom::getObject(int index)
{
return this->objects.at(index);
}
bool AdvRoom::hasBeenVisited()
{
bool truth = this->isVisited;
return truth;
}
void AdvRoom::setVisited(bool flag)
{
this->isVisited = flag;
}
vector<AdvMotionTableEntry> AdvRoom::getMotionTable()
{
vector<AdvMotionTableEntry> copyMotionTable = this->motionTable;
return copyMotionTable;
}
int AdvRoom::getRoomNumber()
{
int copyNumber = this->number;
return copyNumber;
}

Bug color with my console menu

I am trying to do a menu driven by the keyboard's arrows. For this, I change the background of the selected item, like this:
But once I go to the last item and go up again, this happens:
There is my code for the selected items:
void Print::Select(int pos, int realpos)
{
if (pos == realpos)
SetconsoleTextAttribute(handle, 112);
else
SetConsoleTextAttribute(handle, m_white);
}
The entire code:
#include <Windows.h>
#include <iostream>
#include <conio.h>
#include "Options.hpp"
#include <math.h>
#define left_arrow 75
#define right_arrow 77
#define down_arrow 80
#define up_arrow 72
#define page_up 73
#define page_down 81
Config g_options;
class Print
{
public:
void Infos();
void State(bool state);
void Select(int pos, int realpos);
void Loop();
void CheckInput();
int m_red = 0xC;
int m_green = 0xA;
int m_white = 0x7;
int m_selection_color = 70;
char m_input;
int m_min = 1;
int m_max = 0;
unsigned int m_selection_pos = 1;
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
}; extern Print g_print;
void Print::CheckInput()
{
m_input = _getch();
Sleep(30);
if (m_input == page_up && g_options.current_tab != g_options.tabs[3])
g_options.current_tab = g_options.tabs[rand() % 3];
else if (m_input == page_down && g_options.current_tab != g_options.tabs[0])
g_options.current_tab = g_options.tabs[rand() % 3];
if (m_input == up_arrow && m_selection_pos != m_min)
m_selection_pos -= 1;
else if (m_input == down_arrow && m_selection_pos != m_max)
m_selection_pos += 1;
else if (m_input == left_arrow || m_input == right_arrow)
{
if (g_options.current_tab == g_options.tabs[0])
{
switch (m_selection_pos)
{
case 1:
g_options.aim_enabled = !g_options.aim_enabled; break;
case 2:
g_options.aim_autoconfig = !g_options.aim_autoconfig; break;
case 3:
g_options.aim_rcs = !g_options.aim_rcs; break;
case 4:
if (m_input == right_arrow) { g_options.aim_smooth++; break; }
else if (m_input == left_arrow) { g_options.aim_smooth--; break; }
}
}
if (g_options.current_tab == g_options.tabs[1])
{
switch (m_selection_pos)
{
case 1:
g_options.esp_enabled = !g_options.esp_enabled; break;
case 2:
g_options.esp_ennemies = !g_options.esp_ennemies; break;
case 3:
g_options.esp_friends = !g_options.esp_friends; break;
}
}
if (g_options.current_tab == g_options.tabs[2])
{
switch (m_selection_pos)
{
case 1:
g_options.trigger_enabled = !g_options.trigger_enabled;
case 2:
g_options.triggerbot_ennemies = !g_options.esp_ennemies;
case 3:
g_options.trigger_team = g_options.trigger_team;
case 4:
if (m_input == left_arrow) { g_options.trigger_delay -= 1; break; }
else if (m_input == right_arrow) { g_options.trigger_delay += 1; break; }
}
}
if (g_options.current_tab == g_options.tabs[3])
g_options.noflash_enabled = !g_options.noflash_enabled;
}
}
void Print::Select(int pos, int realpos)
{
if (pos == realpos)
{
SetConsoleTextAttribute(handle, 112);
}
else if (pos != realpos)
SetConsoleTextAttribute(handle, m_white);
}
void Print::State(bool state)
{
if (state)
{
SetConsoleTextAttribute(handle, m_green);
printf("[ON]\n");
SetConsoleTextAttribute(handle, m_white);
}
else if (!state)
{
SetConsoleTextAttribute(handle, m_red);
printf("[OFF]\n");
SetConsoleTextAttribute(handle, m_white);
}
}
void Print::Infos()
{
system("cls");
std::cout << "========= " << g_options.current_tab << " =========" << std::endl << std::endl;
if (g_options.current_tab == g_options.tabs[0])
{
Select(1, m_selection_pos); std::cout << "Enabled: "; State(g_options.aim_enabled);
Select(2, m_selection_pos); std::cout << "Autoconfig: "; State(g_options.aim_autoconfig);
Select(3, m_selection_pos); std::cout << "Recoil control: "; State(g_options.aim_rcs);
Select(4, m_selection_pos); std::cout << "Smooth: " << g_options.aim_smooth;
}
else if (g_options.current_tab == g_options.tabs[1])
{
Select(1, m_selection_pos); std::cout << "Enabled: "; State(g_options.esp_enabled);
Select(2, m_selection_pos); std::cout << "Glow ennemy: "; State(g_options.esp_ennemies);
Select(3, m_selection_pos); std::cout << "Glow team: "; State(g_options.esp_friends);
}
else if (g_options.current_tab == g_options.tabs[2])
{
Select(1, m_selection_pos); std::cout << "Enabled: "; State(g_options.trigger_enabled);
Select(2, m_selection_pos); std::cout << "Shoot ennemy: "; State(g_options.triggerbot_ennemies);
Select(3, m_selection_pos); std::cout << "Shoot team: "; State(g_options.trigger_team);
Select(4, m_selection_pos); std::cout << "Delay: " << g_options.trigger_delay;
}
else if (g_options.current_tab == g_options.tabs[3])
{
Select(1, m_selection_pos); std::cout << "Noflash: "; State(g_options.noflash_enabled);
}
}
void Print::Loop()
{
while (true)
{
Infos();
if (g_options.current_tab == g_options.tabs[0] || g_options.current_tab == g_options.tabs[2])
m_max = 4;
else if (g_options.current_tab == g_options.tabs[1])
m_max = 3;
else if (g_options.current_tab == g_options.tabs[3])
m_max = 1;
CheckInput();
}
}
I just noticed that the bug occurs only with the smooth option

Getting a "vector subscript out of range" error when passing a vector into a function: c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write a c++ program that assembles MIPS instructions. While debugging, it keeps throwing an error at line 74 of my main:
myassembler.add(lexed[i].labels[0], lexed[i].name, tokens, i);
my main is here:
#include <fstream>
#include <iostream>
#include <iomanip>
#include <memory>
#include <stdexcept>
#include <string>
#include <sstream>
#include <vector>
#include "exceptions.h"
#include "lexer.h"
#include "util.h"
#include "assembler.h"
std::string read_file(const std::string& name) {
std::ifstream file(name);
if (!file.is_open()) {
std::string error = "Could not open file: ";
error += name;
throw std::runtime_error(error);
}
std::stringstream stream;
stream << file.rdbuf();
return std::move(stream.str());
}
int main(int argc, char** argv) {
// Adjusting -- argv[0] is always filename.
--argc;
++argv;
if (argc == 0) {
std::cerr << "Need a file" << std::endl;
return 1;
}
assembler myassembler;
for (int i = 0; i < argc; ++i) {
std::string asmName(argv[i]);
if (!util::ends_with_subseq(asmName, std::string(".asm"))) {
std::cerr << "Need a valid file name (that ends in .asm)" << std::endl;
std::cerr << "(Bad name: " << asmName << ")" << std::endl;
return 1;
}
// 4 is len(".asm")
auto length = asmName.size() - string_length(".asm");
std::string baseName(asmName.begin(), asmName.begin() + length);
std::string objName = baseName + ".obj";
try {
auto text = read_file(asmName);
try {
auto lexed = lexer::analyze(text); // Parses the entire file and returns a vector of instructions
for (int i =0; i < (int)lexed.size(); i++){
if(lexed[i].labels.size() > 0) // Checking if there is a label in the current instruction
std::cout << "label = " << lexed[i].labels[0] << "\n"; // Prints the label
std::cout<< "instruction name = " << lexed[i].name<< "\n"; // Prints the name of instruction
std::cout << "tokens = ";
std::vector<lexer::token> tokens = lexed[i].args;
for(int j=0; j < (int)tokens.size(); j++){ // Prints all the tokens of this instruction like $t1, $t2, $t3
if (tokens[j].type == lexer::token::Integer)
std::cout << tokens[j].integer() << " ";
else
std::cout << tokens[j].string() << " ";
}
myassembler.add(lexed[i].labels[0], lexed[i].name, tokens, i);
myassembler.p();
std::cout << "\n\n\n";
}
} catch(const bad_asm& e) {
std::stringstream error;
error << "Cannot assemble the assembly code at line " << e.line;
throw std::runtime_error(error.str());
} catch(const bad_label& e) {
std::stringstream error;
error << "Undefined label " << e.what() << " at line " << e.line;
throw std::runtime_error(error.str());
}
} catch (const std::runtime_error& err) {
std::cout << err.what() << std::endl;
return 1;
}
}
/*getchar();*/
return 0;
}
assembler.h:
#include "lexer.h"
#include <fstream>
#include <vector>
#include <string>
struct symbol
{
std::string label = "";
int slinenum;
};
struct relocation
{
std::string instruct = "";
std::string label = "";
int rlinenum;
int rt = 0;
int rs = 0;
};
struct opcode
{
std::string instruct = "";
int opc = 0;
bool isloadstore = false;
int extType = 0;
bool isbranch = false;
};
struct function
{
std::string instruct = "";
int funct = 0;
bool isjr = false;
bool isshift = false;
};
struct regs
{
std::string name;
int num;
};
enum instrtype
{
R, I, neither
};
class assembler
{
public:
assembler();
void oinit(void);
void finit(void);
void rinit(void);
void printToFile(std::fstream &file);
void savesymb(std::string label, int line);
void saverel(std::string instr, std::string label, int line, int rt, int rs);
std::vector<int> formatr(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line);
int formatr(std::string instr, lexer::token toke, int line);
std::vector<int> formati(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line);
std::vector<int> formati(std::string instr, lexer::token toke1, lexer::token toke2, int line);
int findnum(std::string regname);
void add(std::string label, std::string instr, const std::vector<lexer::token> &tokens, int linen);
void secAdd(void);
int rassemble(std::string instr, int rd, int rs, int rt, int shamt);
int iassemble(std::string instr, int rt, int rs, int imm);
void p();
private:
std::vector<int> results;
std::vector<symbol> symbtable;
std::vector<relocation> reloctable;
std::vector<opcode> ops;
std::vector<function> functions;
std::vector<regs> registers;
instrtype type = neither;
};
and assembler.cpp:
// ECE 2500
// Project 1: myAssembler
// assembler.cpp
// Sheila Zhu
#include "lexer.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "assembler.h"
assembler::assembler()
{
oinit();
finit();
rinit();
}
void assembler::oinit()
{
opcode myop;
myop.instruct = "addi";
myop.opc = 8;
myop.extType = 1;
ops.push_back(myop);
// more of the same
}
void assembler::finit()
{
function myfunc;
myfunc.instruct = "add";
myfunc.funct = 32;
functions.push_back(myfunc);
// more of the same
}
void assembler::rinit()
{
regs myreg;
myreg.name = "$zero";
myreg.num = 0;
registers.push_back(myreg);
//more of the same
}
void assembler::printToFile(std::fstream &file)
{
for (int i = 0; i < (int)results.size(); i++)
file << results.at(i) << std::endl;
}
void assembler::savesymb(std::string label, int line)
{
symbol symb;
symb.label = label;
symb.slinenum = line * 4;
symbtable.push_back(symb);
}
void assembler::saverel(std::string instr, std::string label, int line, int rt, int rs)
{
relocation re;
re.instruct = instr;
re.label = label;
re.rlinenum = line;
re.rt = rt;
re.rs = rs;
}
int assembler::findnum(std::string regname)
{
for (int i = 0; i < (int)registers.size(); i++)
{
if (regname == registers.at(i).name)
return registers.at(i).num;
}
return -1;
}
std::vector<int> assembler::formatr(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line)
{
int rd = 0, rs = 0, rt = 0, shamt = 0;
std::vector<int> x;
function currf;
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
currf = functions.at(i);
}
try
{
if (currf.isshift)
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rd = findnum(toke1.string());
if (rd == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
{
shamt = toke3.integer();
if (shamt < 0)
throw 3;
}
else
throw 1;
}
else
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rd = findnum(toke1.string());
if (rd == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke3.string());
if (rt == -1)
throw 2;
}
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else if (e == 2)
std::cerr << "Invalid register name in line " << line << std::endl;
else
std::cerr << "Shift amount cannot be negative in line " << line << std::endl;
}
x.push_back(rd);
x.push_back(rs);
x.push_back(rt);
x.push_back(shamt);
return x;
}
int assembler::formatr(std::string instr, lexer::token toke, int line)
{
int rs = 0;
try
{
if (toke.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke.string());
if (rs == -1)
throw 2;
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
return rs;
}
std::vector<int> assembler::formati(std::string instr, lexer::token toke1, lexer::token toke2, lexer::token toke3, int line)
{
int rt = 0, rs = 0, imm = 0;
std::vector<int> x;
opcode currop;
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
currop = ops.at(i);
}
try
{
if (currop.isbranch)
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
imm = toke3.integer();
else
saverel(instr, toke3.string(), line, rt, rs);
}
else if (currop.isloadstore)
{
if ((instr == "lbu") || (instr == "sb"))
{
if (toke2.type == lexer::token::String)
throw 1;
else
{
if (toke2.integer() < 0)
imm = (0xFFFF << 16) + (0xFF << 8) + toke2.integer();
else
imm = toke2.integer();
}
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
}
else
{
if (toke2.type == lexer::token::String)
throw 1;
else
{
if (toke2.integer() < 0)
imm = (0xFFFF << 16) + toke2.integer();
else
imm = toke2.integer();
}
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
}
}
else
{
if ((instr == "andi") || (instr == "ori"))
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
imm = toke3.integer();
else
throw 1;
}
else
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::Integer)
throw 1;
else
{
rs = findnum(toke2.string());
if (rs == -1)
throw 2;
}
if (toke3.type == lexer::token::Integer)
{
if (toke3.integer() < 0)
imm = (0xFFFF << 16) + toke2.integer();
else
imm = toke3.integer();
}
else
throw 1;
}
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
x.push_back(rt);
x.push_back(rs);
x.push_back(imm);
return x;
}
std::vector<int> assembler::formati(std::string instr, lexer::token toke1, lexer::token toke2, int line)
{
int rt = 0, imm = 0;
std::vector<int> rval;
try
{
if (toke1.type == lexer::token::Integer)
throw 1;
else
{
rt = findnum(toke1.string());
if (rt == -1)
throw 2;
}
if (toke2.type == lexer::token::String)
throw 1;
else
imm = toke2.integer();
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong argument in line " << line << std::endl;
else
std::cerr << "Invalid register name in line " << line << std::endl;
}
rval.push_back(rt);
rval.push_back(imm);
return rval;
}
void assembler::add(std::string label, std::string instr, const std::vector<lexer::token> &token, int linen)
{
int assembled = 0, rd = 0, rt = 0;
std::vector<int> argh;
int arg;
if (label.length() > 0)
savesymb(label, linen);
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
type = R;
}
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
type = I;
}
if (type == R)
{
try
{
if (instr == "jr")
{
if ((int)token.size() == 1)
{
arg = formatr(instr, token.at(0), linen);
assembled = rassemble(instr, rd, arg, rt, 0);
}
else
throw 1;
}
else
{
if ((int)token.size() == 3)
{
argh = formatr(instr, token.at(0), token.at(2), token.at(3), linen);
assembled = rassemble(instr, argh[0], argh[1], argh[2], argh[3]);
}
else
throw 1;
}
}
catch (int e)
{
if (e == 1)
std::cerr << "Wrong number of arguments at line " << linen << std::endl;
}
}
else if (type == I)
{
try
{
if (instr == "lui")
{
if ((int)token.size() == 2)
{
argh = formati(instr, token.at(0), token.at(1), linen);
assembled = iassemble(instr, argh[0], 0, argh[1]);
}
else
throw 1;
}
else
{
if ((int)token.size() == 3)
{
argh = formati(instr, token.at(0), token.at(1), token.at(2), linen);
assembled = iassemble(instr, argh[0], argh[1], argh[2]);
}
else
throw 1;
}
}
catch (int e)
{
if (e == 1)
std::cout << "Wrong number of arguments at line " << linen << std::endl;
}
}
else
std::cerr << "Instruction not recognized at line " << linen << std::endl;
results.push_back(assembled);
}
void assembler::secAdd(void)
{
std::vector<int>::iterator iter = results.begin();
for (int i = 0; i < (int)reloctable.size(); i++)
{
for (unsigned int j = 0; j < symbtable.size(); j++)
{
if (reloctable.at(i).label == symbtable.at(j).label)
{
int assembled = 0;
iter += (reloctable.at(i).rlinenum / 4);
for (unsigned int k = 0; k < ops.size(); k++)
{
if (reloctable.at(i).instruct == ops.at(k).instruct)
type = I;
}
if (type == I)
assembled = iassemble(reloctable.at(i).instruct, reloctable.at(i).rt, reloctable.at(i).rs, symbtable.at(i).slinenum);
else
std::cerr << "Instruction not recognized at line " << reloctable.at(i).rlinenum << std::endl;
results.erase(iter);
results.insert(iter, assembled);
}
}
}
}
int assembler::rassemble(std::string instr, int rd, int rs, int rt, int shamt)
{
int func = 0;
int code = 0;
for (int i = 0; i < (int)functions.size(); i++)
{
if (instr == functions.at(i).instruct)
{
func = functions.at(i).funct;
break;
}
else
{
if (i == (functions.size() - 1))
return -1;
}
}
code = (rs << 21) + (rt << 16) + (rd << 11) + (shamt << 6) + func;
return code;
}
int assembler::iassemble(std::string instr, int rt, int rs, int imm)
{
int op = 0;
int code = 0;
for (int i = 0; i < (int)ops.size(); i++)
{
if (instr == ops.at(i).instruct)
{
op = ops.at(i).opc;
break;
}
else
{
if (i == (ops.size() - 1))
return -1;
}
}
code = (op << 26) + (rs << 21) + (rt << 16) + imm;
return code;
}
void assembler::p()
{
for (int i = 0; i < (int)results.size(); i++)
std::cout << results.at(i) << " ";
std::cout << std::endl;
}
When debugging, the tokens parameter triggers the error, and the this pointer in the vector code shows that the vector size changes to 0 at these lines:
#if _ITERATOR_DEBUG_LEVEL == 2
if (size() <= _Pos)
What exactly is happening?
Sorry if my formatting is bad/wrong, etc., and please let me know if I should make any edits/provide more code.
Thanks in advance.
The error is caused by accessing by index vector element that does not exist.
In you case lexed[i] should be valid. So, the only possible issue may be with empty labels vector. Validate this vector before accessing its elements, for example
myassembler.add(lexed[i].labels.empty() ? "" : lexed[i].labels[0],
lexed[i].name, tokens, i);
Actually there is one more bug for very large lexed arrays when integer index may overflow. You should not cast result of .size() to int. Instead proper type should be used for i:
for (size_t i = 0; i < lexed.size(); i++)