I am trying to create a keygen to some reversing challenges around there.
I decided to try to code it in a language that I don't know well, c++
I not sure how to use pointers yet, but I thing that I implemented the algorithm well without them. the only problem is that I print the answer I get it's memory location instead all the string.
char decrypt(char c, int position);
int main(){
cout << "Enter username:" << endl;
string username;
string answer[20] = "";
cin >> username;
for (int i = username.length(); i > 0; i--){
answer[username.length() - i] = decrypt(username[i-1],i);
if (i == 0){
answer[username.length() +1] = '\0';
}
}
return 0;
}
char decrypt(char c, int position)
{
if (position == 4){
return '-'; }
if (c > 'M'){
c -= 17; }
else{
c += 21; }
c ^= position;
c ^= 2;
return c;
}
If I will try to print the string username I will get the string and not the memory location of username. So I'm not sure what is going on..
Thanks for any help,
Or
First, try to use the answer variable as a string and not a char*. A string authomatically resize and realocates its internal buffer if needed.
The code could looks like this:
string username;
string answer;
cin >> username;
for (int i = 0; i < username.length(); i++)
{
answer += decrypt(username[i],i+1);
}
Then if you want to see the content of the internal string buffer, you can use answer.c_str ();
Edit:
As songyuanyao said, your code uses an array of string. But the solution of using an array of 20 chars (char answer [20]) leads to a memory issue if the username has a size of 20 or more.
If I understand your question correctly,
string answer[20] = "";
should be
char answer[20];
string answer[20] is array of std::string, not the c-style string (i.e. char[]).
In this code, answer is not a string – it is an array of 20 strings. You probably want char answer[20], or, more likely, to create a single string answer and append the result with answer += character.
Related
I tried to create a code that reverse a string, I think my loops logic is correct. But I don't know what is wrong.
#include <iostream>
int main(){
std::cout<<"How many letters does your string have >> ";
int nbre;
std::cin>> nbre;
int a;
a=nbre-1;
char normal[a]={};
char reverse[a]={};
std::cout<<"Enter your string >> ";
std::cin >> normal;
for (int i=0;i<=a;i++){
normal[i]=reverse[a-i];
}
std::cout << "The reversed string is >> " << std::endl;
for (int u=0; u<=a; u++){
std::cout<<reverse[u];
}
return 0;
}
enter image description here
You have to use constant to declare an array this way:
char normal[a]={};
char reverse[a]={};
You can allocate memory like this instead:
char* normal = (char*)calloc(a+1, sizeof(char));
char* reverse = (char*)calloc(a+1, sizeof(char));
and free it once done using it.
The +1 is because you have to account for the ending null char.
I don't think letting the user account for it is a good idea unless your users will only be C-programmers... Better change a = nbre-1; to a=nbre;.
Finally, you should have meant to write your for-loop as:
for (int i = 1; i <= a; i++) {
reverse[i-1] = normal[a - i];
}
I made many changes to your for loop. I will let you do the Homework to understand why.
Personally, I would load the input string into a char array and iterate backwards, starting at the end of the input array and just doing some index math.
Let n = input string length
Iterate from i = n-1 to 0, and load input[i] into reversed[n-i]. Luceion is correct; you're not doing the correct method of actually reversing input string in the first for loop.
I have a for loop that returns the user's input backwards. They enter a string, and the loop reverses it. Here's what it looks like:
string input; //what user enters
const char* cInput = input.c_str(); //input converted to const char*
for(int i = strlen(cInput) - 1; i >= 0; i--)
cout << input[i]; //Outputs the string reversed
Instead of having cout << input[i], how can I set input[i] as the value of a new string? Like I want to have a string called string inputReversed and set it equal to input[i].
In other words, if input == hello, and input[i] == olleh, I want to set inputReversed equal to olleh.
Is this doable? Thanks!
string inputReversed(input.rbegin(), input.rend());
Just declare the output string and append to it, either with += or the append member function:
string inputReversed;
for(int i = input.size() - 1; i >= 0; i--)
inputReversed += input[i]; // this
// inputReversed.append(input[i]); // and this both do the same thing
Note that you don't need c_str and strlen, you can simply use the size or length member function.
You can also make the code more readable by using std::reverse:
string inputReversed = input;
std::reverse(inputReversed.begin(), inputReversed.end());
Or std::reverse_copy, since you're making a copy of the original string anyway:
string inputReversed;
std::reverse_copy(input.begin(), input.end(), std::back_inserter(inputReversed));
If i understand what you are asking you want to have a variable to store the reversed string and output that?
If so you can just do this
string input, InputReversed;
//what user enters
const char* cInput = input.c_str(); //input converted to const char*
for(int i = strlen(cInput) - 1; i >= 0; i--){
InputReversed += input[i];
}
cout << InputReversed; //Outputs the string reversed
Going off of this thread may help you.
How do I concatenate const/literal strings in C?
It seems like what you want is to create a new string which at the end of the loop will contain the backwards input.
string input; //what user enters
const char* cInput = input.c_str(); //input converted to const char*
char inputReversed[len(input)];
for(int i = strlen(cInput) - 1; i >= 0; i--)
output = strcpy(output, input[i]); //Outputs the string reversed
Basically, here, I'm trying to reverse an array, and convert the reversed int array into a string (I'm trying to write the equivalent of Java's BigInteger class in C++ - basically turning the input into big endian ordering, breaking down the operations, reversing the result back to little endian format, and returning the string).
And as you can see below, it outputs some strange characters (I think it's an out of range reference?) - but I'm not entirely sure what caused this output?
I would really appreciate if you could take a look at it:
Sample input
int a[] = {1, 2, 3};
int rA[3];
reverseIntArray(a, rA, 3);
string aString = intArrayToString(a, 3);
cout << aString << endl;
Console output
123\216\377
As you can see - it calculates the answer correctly, with the exception of the \277_\377.
I'll post the rest of the relevant functions:
reverseIntArray
void reverseIntArray(int array[], int reversedArray[], int arrayLength) {
for (int i = 0; i < arrayLength; i++) {
reversedArray[i] = array[arrayLength - 1 - i];
}
}
intArrayToString
string intArrayToString(int digits[], int length) {
// convert int array to char array
char digitsChar[length];
for (int i = 0; i < length; i++) {
digitsChar[i] = '0' + digits[i];
}
// convert char array to string
string intString(digitsChar);
return intString;
}
I'm quite sure this is a subtle issue to do with pointers, but I'm still relatively new to C++ (migrating from Java) and I've stared at this for hours but haven't come up with any ideas.
The std::string constructor you are using is assuming that the string you pass is properly terminated, which it isn't and that leads to undefined behavior as the std::string constructor goes beyond the end of the digitsChar array.
Three possible solutions:
Make room for another character in the digitsChar array and terminate it:
char digitsChar[size + 1];
for (...) { ... }
digitsChar[3] = '\0';
string intString(digitsChar);
Use another constructor where you pass the length of the character array:
string intString(digitsChar, length);
Append the characters directly to the string:
string intString;
for (int i = 0; i < length; i++) {
intString += '0' + digits[i];
}
There are of course other solutions as well, like for example using std::ostringstream.
so I'm working on a project that I have to read contents from a file and then analyze them. But I'm having a problem with getting the string out of a pointer that contains the address to what I need.
string lePapel(vector<char> vec){
string *str, s;
int i, j = 0;
vector<char> aux;
aux.resize(6);
for (i = 57; i <= 62; i++){
aux[j] = vec[i];
j++;
}
str = new string[aux.size()];
for (i = 0; i < 6; i++){ str[i] = aux[i]; }
return s;
}
So, the file contains in the array positions from 57 to 62 the word: ABCB4, but when returning the string s my output is A only as expected because of the pointer.
The thing is that I have been trying to find a solution and storing the whole content from vec[57] to vec[64] into the string s and returning it, and the closest that I got to returning anything plausible was using a pointer.
So, now to my question, how can I iterate the *str pointer and copy the whole content to s and return it?
Thanks in advance
I'd suggest you to not use pointers on string in your case. The following code is probably what you want :
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string lePapel(vector<char> vec){
int j = 0;
vector<char> aux;
aux.resize(6);
for (int i = 57; i <= 62; i++){
aux[j] = vec[j];
j++;
}
string str;
str.reserve(6);
for (int i = 0; i < 6; i++){ str.push_back(aux[i]); }
return str;
}
int main() {
char x[5] = {'A', 'B', 'C', 'B', '4'};
vector<char> vec(x, x + 5);
string s = lePapel(vec);
cout << s;
return 0;
}
Tested here : Tested code
About reserving space to your vector : c++ vector::reserve
Same for strings : reserve for strings
The dynamic array of string objects and the whole aux vector seem completely needless here (unless there's some other purpose for them in your code). Additionally, str is currently causing a memory leak because you never delete it when you're finished.
A much simpler approach is just to append the characters one-at-a-time to the s string object (assuming it's a std::string):
string lePapel(vector<char> vec) {
string s;
for (int i = 57; i <= 62; i++) {
s += vec[i];
}
return s;
}
There are various ways to make the code even shorter (and more efficient) than that though, if you really want to.
EDIT: If you still need/want to iterate your dynamic array and concatenate the contents into s, here's how you could do it:
for (i = 0; i < 6; i++) s += str[i];
delete [] str; //<-- very important!
Short answer, you don't want a string * you want a char *. What you created is a string array. String objects contain a pointer to the char * data you are trying to capture. Also, the sizeof(std::string) (8 bytes in size) is a lot bigger than sizeof(char) (1 byte in size) the second character you store is 8 bytes away from the first character instead of being adjacent.
There are a lot of other C++ style and safety concerns, but I'll stick with the question. ;)
this question should be easy and straight forward, but after searching online, I couldn't find an answer. might because the question is just too simple.
following code is from cplusplus.com. it's a function of making a string lowercase. I was intended to do something similar.
/* tolower example */
#include <stdio.h>
#include <ctype.h>
int main ()
{
int i=0;
char str[]="Test String.\n";
char c;
while (str[i])
{
c=str[i];
putchar (tolower(c));
i++;
}
return 0;
}
and what I made is this:
void search(string A[], string B[], int k)
{
int temp;
for(int j = 0; j <= 4; j++)
{
for(int i = 0; i <= k; i++)
{
string str (A[i]);
int h = 0;
char lstr[] = B[j];
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
string key (B[j]);
.....
this part of the code is in a for loop. B[j] is a string array.
Visual Studio informed me that char lstr[] = B[j]; part is not right, the error message is:
Error: initialization with '{...}' expected for aggregate object.
I think the problem is that I didn't use the correct syntax of using a string array in a function. something should be done for B[j], in order to make it a char array. I couldn't figure it out.
is that something about pointer? sorry I haven't learn pointer yet.
does my question make sense for you? any help is greatly appreciated!!
If you're looking to make the letters in the string lowercase it's more readable to just work with strings all the way and use std::transform. For example,
// make sure to #include <algorithm>
// at the top
string lstr = B[j];
std::transform(lstr.begin(), lstr.end(), lstr.begin(), ::tolower);
This is much more natural and c++ idiomatic than working with char * directly and less error-prone.
You're trying to assign a char to char[]. You can get the effect you want with the following code:
....
int h = 0;
char* lstr = &B[j]; // point lstr to the address of j'th element of B.
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
.....
What this does is that lstr is now a pointer that points to the j'th character in B. Arrays are essentially pointers. When you do B[j], it's equivalent to writing char ch = *(B + j);, where B points to the address of the first character in the array of characters (otherwise known as string).
EDIT
After your edit, it now seems that you're trying to assign a std::string to a char. Here is the corrected solution.
....
int h = 0;
string& lstr = B[j]; // grab a reference to the j'th string in B.
char c;
while (lstr[h])
{
c = lstr[h];
putchar (tolower(c));
h++;
}
.....
Here, lstr is essentially a reference to the j'th string in B and you can use it as a regular string just like how you're using string str(A[i]);, which makes a copy of the i'th string in A.
You're confusing character arrays and string objects here. A character array is an array of bytes of set size which is null terminated, while a string is an object which expands/contracts as is necessary and doesn't require the null terminator. You're attempting to assign a string object to a character array, which is unsupported. If you're working with string objects, and want to retrieve their equivalent character array, utilize the c_str() function:
const char* lstr = B[j].c_str()
Also, utilizing an array name of B and an index of j is hilarious.