I'm fairly new to c/c++ programming and currently I'm working on some basic programms to get in touch with the language. My newest programm is a simple hex_xor function, that follows the instruction of Cryptopals Challenge 2. But I'm already getting errors and I'm assuming I am doing something horribly wrong with the pointers I am using.
Here is a part of my programm:
const char* hex_char_to_bin(char c)
{
switch(toupper(c))
{
case '0': return "0000";
case '1': return "0001";
case '2': return "0010";
case '3': return "0011";
case '4': return "0100";
case '5': return "0101";
case '6': return "0110";
case '7': return "0111";
case '8': return "1000";
case '9': return "1001";
case 'A': return "1010";
case 'B': return "1011";
case 'C': return "1100";
case 'D': return "1101";
case 'E': return "1110";
case 'F': return "1111";
}
}
const char* hex_binary(const char* c){
std::string result = "";
for(int i = 0; i < strlen(c); i++){
result += hex_char_to_bin(c[i]);
}
return result.c_str();
}
int main(){
std::string s1 = "1c0111001f010100061a024b53535009181c";
std::string s2 = "686974207468652062756c6c277320657965";
const char* bin1 = hex_binary(s1.c_str());
const char* bin2 = hex_binary(s2.c_str());
std::cout << bin1 << "\n" << bin2 << std::endl;
return 0;
}
The output is the following:
011010000110100101110100001000000111010001101000011001010010000001100010011101010110110001101100001001110111001100100000011001010111100101100101
011010000110100101110100001000000111010001101000011001010010000001100010011101010110110001101100001001110111001100100000011001010111100101100101
In both variables (bin1/2) is the binary conversion of the second hex-string. My aim is (obviously) to have both binary-strings saved in different variables, so I can proceed with my xor-function. Can someone point out where I am failing to achieve my goal and why? Other hints are welcome aswell!
You can't use result of c_str() when main string object is no longer alive. So, you're referencing already freed resources and facing undefined behavior.
If I were you, I'd change hex_binary() to return std::string and just return result back without using c_str()
Related
I'm trying to avoid using a pointer for an assignment
When I avoid using a pointer, my code doesn't work, so I'm not really sure what to do.
How would I change this code to not use a pointer?
char* removeVowels(char* userInput) {
int j = 0;
char* noVowels = new char[100];
for (int i = 0; i < strlen(userInput); i++) {
char character = userinput[i];
switch (character) {
case 'a':
case 'A':
case 'E':
case 'e':
case 'i':
case 'I':
case 'o':
case 'O':
case 'U':
case 'u':
continue;
default:
noVowels[j++] = character;
}
}
noVowels[j] = '\0';
return noVowels;
}
To avoid pointers you need to change the interface.
You cannot avoid pointers if you don't change the function declaration because it obviously uses pointers.
The function should probably take a const std::string& and return a std::string (requires #include<string>):
std::string removeVowels(const std::string& userInput) {
std::string noVowels;
for(char character : userInput) {
//...
// use `noVowels.push_back(character)` to append `character` to `noVowels`
//...
}
return noVowels;
}
This will then also require appropriate changes at the call site.
If you don't know what const and/or & means, then use just std::string instead of const std::string&.
I have a question about logic flow:
I'm trying to create a calculator functionality that:
1.lets you assign a declare a variable (eg, let x = 5;)
2. that will also let you reassign a value (eg, x = 10;)
3. will let you use values in expressions (eg, x + 5; returns 15)
The bottom function statement() is supposed to decide if Token Token_stream::get()
returns a declaration, reassignment, or expression then run the appropriate code.
In making it so that Token_stream::get() returns name to statement()
and calls the reassignment. I lost the functionality to
have an expression() start with a name. Eg. If I write
x + 5;
It will throw an error from assignment because it reads the x and looks for a =
instead of calling expression.
I want to create special token for assignment to use in statement() if Token Token_stream::get() reads a string followed by a '=', but then put the name back into the input stream so I can grab if for the assignment. Does any have any suggestions?
//------------------------------------------------------------------------------
Token Token_stream::get()
{
if (full) { full=false; return buffer; }
char ch;
cin >> ch;
switch (ch) {
case '(':
case ')':
case '+':
case '-':
case '*':
case '/':
case '%':
case ';':
case '=':
case ',':
return Token(ch);
case '.':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{ cin.unget();
double val;
cin >> val;
return Token(number,val);
}
default:
if (isalpha(ch)) {
string s;
s += ch;
while(cin.get(ch) && (isalpha(ch) || isdigit(ch))|| ch =='_' ) s+=ch;
cin.unget();
if (s == "let") return Token(let);
if (s == "const") return Token(constant);
if (s == "q") return Token(quit);
if (s == "sqrt") return Token(square_root);
if (s == "pow") return Token(exponent);
return Token(name,s);
}
error("Bad token");
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------
double statement()
{
Token t = ts.get();
switch(t.kind)
{
case let:
return declaration();
case name:
ts.unget(t);
return assigment();
case constant:
return declare_constant();
default:
ts.unget(t);
return expression();
}
}
//----
I wouldn't put error handling logic inside a tokenizer class - it's supposed to be a pretty dumb text muncher that just splits it on whitespaces and returns tokens to the caller.
So lets say you start parsing a statement and your tokeninizer returns let. Now you know that what follows is supposed to be a declaration. The next token should be a unique name of a variable that doesn't exists yet. So you call Token_stream::get() again and see what you get. On success, you get the next token and see if you get a =. Etc.
Similarly - you get a name of a variable as a first token of a statement. You check whether it has been declared yet and report an error if it hasn't. You check another token. It's supposed be an operator of some sort (that probably includes =). If you get it, you start looking for a valid term (a value, another variable, an expression...). Etc.
UPDATE
I thought stoi(string) solved it, but it only worked for a little while.
I have added the code for splitString and decrypt below.
I occasionally get unhandled exceptions with atoi() using the supposable same value.
My code looks like this:
ifstream myfile ("Save.sav");
string line = "";
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
}
myfile.close();
line = StaticFunctions::decrypt(line);
}
vector<string> splitString = StaticFunctions::splitString(line, 's');
return atoi(splitString[0].c_str());
So what it does is reading a savefile, then it decrypts it and then it splits the string by every 's'. When I'm debugging, the savefile is always the same and the first value is 3.
This work sometimes, maybe every 10 attempt. So every 9 out of 10 attempts I get unhandled exception at ... at memory location.
Monitoring the converted value shows it always returns 3 and then the application doesn't crash until I start the game which is a bit further in the code.
If I remove the atoi and just return 3 the application works fine.
I've tried strtod but it didn't help.
Thanks,
Markus
SplitString code:
vector<string> StaticFunctions::splitString(string str, char splitByThis)
{
vector<string> tempVector;
unsigned int pos = str.find(splitByThis);
unsigned int initialPos = 0;
// Decompose statement
while( pos != std::string::npos ) {
tempVector.push_back(str.substr( initialPos, pos - initialPos + 1 ) );
initialPos = pos + 1;
pos = str.find(splitByThis, initialPos );
}
// Add the last one
tempVector.push_back(str.substr(initialPos, std::min(pos, str.size()) - initialPos + 1));
return tempVector;
}
Decrypt code (very simple):
string StaticFunctions::decrypt(string decryptThis)
{
for(int x = 0; x < decryptThis.length(); x++)
{
switch(decryptThis[x])
{
case '*':
{
decryptThis[x] = '0';
break;
}
case '?':
{
decryptThis[x] = '1';
break;
}
case '!':
{
decryptThis[x] = '2';
break;
}
case '=':
{
decryptThis[x] = '3';
break;
}
case '#':
{
decryptThis[x] = '4';
break;
}
case '^':
{
decryptThis[x] = '5';
break;
}
case '%':
{
decryptThis[x] = '6';
break;
}
case '+':
{
decryptThis[x] = '7';
break;
}
case '-':
{
decryptThis[x] = '8';
break;
}
case '"':
{
decryptThis[x] = '9';
break;
}
}
}
return decryptThis;
}
Try use strtol instead
strtol (splitString[0].c_str(),NULL,10);
stoi(string) instead of atoi(string.c_str()) solved it.
UPDATE:
It did not solve it.
I want to write a cpp function something similar to this, where outVal should accept data of the corresponding type returned from the respective functions in each case.
void ReadFieldByType(char fieldType, string content, string& outStr, **unknown**& outVal){
unsigned int ifield;
char cField;
string sField;
double dField;
switch (fieldType)
{
case 'c':
ReadChar(content, content, cField);
outVal = cField;
break;
case 'd':
ReadInteger(content, content, ifield);
outVal = ifield;
break;
case 'f':
ReadDouble(content, content, dField);
outVal = dField;
break;
case 's':
ReadString(content, content, sField);
outVal = sField;
break;
default:
break;
}
outStr = content;}
I don't know how to set datatype for outVal. Can this be improved or is there any other choice to accomplish this task?
Take a look at boost::variant.
In your case you would use something like:
typedef boost::variant<char, int double, std::string> out_t;
You could probably do it with templates and the typeid operator:
template<class T>
void ReadField(string content, string& outStr, T& outVal)
{
if (typeid(T) == typeid(int))
ReadInteger(content, content, outVal);
else if (typeid(T) == typeid(char))
ReadChar(content, content, outVal);
else if (typeid(T) == typeid(double))
ReadDouble(content, content, outVal);
else if (typeid(T) == typeid(std::string))
ReadString(content, content, outVal);
outStr = content;
}
Although I have to admit that I don't like the solution.
Use union, it allows to choose type of variable;
union
{
unsigned int ifield;
char cField;
string sField;
double dField;} outVal;
void ReadFieldByType(char fieldType, string content, string& outStr, **unknown**& outVal){
switch (fieldType)
{
case 'c':
ReadChar(content, content, cField);
outVal.cField = cField;
break;
case 'd':
ReadInteger(content, content, ifield);
outVal.ifield = ifield;
break;
case 'f':
ReadDouble(content, content, dField);
outVal.dField = dField;
break;
case 's':
ReadString(content, content, sField);
outVal.sField = sField;
break;
default:
break;
}
outStr = content;}
I wrote a little structure for getting certain time information. This structure is a helper,
for my logging class im planning to write. Here is the code:
struct UTime
{
char Month [4];
char DayOfMonth [3];
char DayOfWeek [4];
char Year [5];
char Time [9];
char Full [25];
UTime()
{
this->refresh();
}
void refresh()
{
char TimeBuffer[26] = {};
time_t RawTime = 0;
time(&RawTime);
ctime_s(TimeBuffer, 26*sizeof(char), &RawTime);
this->DayOfWeek[0] = TimeBuffer[0];
this->DayOfWeek[1] = TimeBuffer[1];
this->DayOfWeek[2] = TimeBuffer[2];
this->DayOfWeek[3] = 0;
this->Month[0] = TimeBuffer[4];
this->Month[1] = TimeBuffer[5];
this->Month[2] = TimeBuffer[6];
this->Month[3] = 0;
this->DayOfMonth[0] = TimeBuffer[8];
this->DayOfMonth[1] = TimeBuffer[9];
this->DayOfMonth[2] = 0;
this->Time[0] = TimeBuffer[11];
this->Time[1] = TimeBuffer[12];
this->Time[2] = TimeBuffer[13];
this->Time[3] = TimeBuffer[14];
this->Time[4] = TimeBuffer[15];
this->Time[5] = TimeBuffer[16];
this->Time[6] = TimeBuffer[17];
this->Time[7] = TimeBuffer[18];
this->Time[8] = 0;
this->Year[0] = TimeBuffer[20];
this->Year[1] = TimeBuffer[21];
this->Year[2] = TimeBuffer[22];
this->Year[3] = TimeBuffer[23];
this->Year[4] = 0;
memcpy(this->Full, TimeBuffer, 25);
this->Full[24] = 0;
}
}; // struct UTime;
Now Id like to add a function wich returns a formatted version of the time information.
For example:
std::string formatted = utime.get(Year, Month)
This function should return something like: "2011 Nov", or another example:
std::string formated = utime.get(DayOfWeek, Time);
This function should return something like: "Mon 20:43:24". Can anyone please point me in the most effecient way to do this? Im just not sure about effeciency because in a logger this function might get called alot. Thank you very much.
You can use strftime. It supports lots of format
std::string utime::get(char* format) {
std::string formatted;
formatted.reserve(30);
for( ; *format!='\0'; ++format) {
if (*format != '%')
formatted.append(*format);
else {
++format;
switch (*format) {
case 'a': formatted.append(DayOfWeek); break;
case 'b': formatted.append(Month); break;
case 'd': formatted.append(DayOfMonth); break;
case 'H': formatted.append(Time, 2); break;
case 'M': formatted.append(Time+3, 2); break;
case 'S': formatted.append(Time+6, 2); break;
case 'x': formatted.append(Month);
formatted.append(' ');
formatted.append(DayOfMonth);
formatted.append(' ');
formatted.append(Year);
break;
case 'X': formatted.append(Time); break;
case 'y': formatted.append(Year+2); break;
case 'Y': formatted.append(Year); break;
case '%': formatted.append('%'); break;
default: throw std::logic_error("Unsupported string format");
};
}
}
return formatted;
}
This should be fairly fast since it reserves a fair amount of space, and simply appends chacters to the end of the already allocated buffer most of the time. I highly recommend matching a standard formatting scheme like strftime as parapura rajkumar suggested.