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.
Related
So I found this code on the internet, but as I'm not that familiar with C++. I found difficult to understand this: how does a vector suddenly becomes a matrix?
int main(){
int n;
string v[MAX];
cin >> n;
for(int i=0;i<n;i++)
cin >> v[i];
for(int i=0;i<n-1;i++){
int y1,y2;
y1=v[i].size();
y2=v[i+1].size();
for(int j=0; j<y1 && j<y2 ;j++)
if(v[i][j]!=v[i+1][j]){ // here <-
int x1,x2;
x1=(int) v[i][j]-'A';
x2=(int) v[i+1][j] - 'A';
m[x1][0]=true;
m[x2][0]=true;
m[x1][x2+1]=true;
break;
}
}
string v[MAX];
is an array of std::string (presumably - this is one reason to avoid using namespace std;. How do I know what type of string it is?).
You can access elements of an array with []:
int someInts[5];
someInts[3]=1000; // sets the 4th int (counting starts from 0)
You can also access characters in a std::string with []:
std::string name("chris");
std::cout << name[3]; // prints 'i'
So you can access the letters in an array of std::strings with two sets of []:
std::string names[10]; // 10 names
names[3] = "chris"; // set the 4th name
std::cout << names[3][1]; // prints 'h'
// ^ access letter in string
// ^ access string in array
Here is a self-explanatory example
int main()
{
std::string name;
name = "test";
for(int i = 0; i<4; i++)
std::cout<<name[i]<<std::endl;
std::cout << "Hello, " << name << "!\n";
}
It will print
t
e
s
t
Hello, test!
So, an array of strings is actually a 2D array of characters, that you called a matrix.
string v[N] is an array of string, string itself is an array of chars.
Since, as the commentor pointed out, there are neither vectors or matrices in the code you gave, I'll make a couple assumptions:
By "vector", you mean "array"
You think that double square brace operators ([][]) indicate a matrix.
If those are both true, I can explain what you're seeing:
string[5] strings = { Some Strings... }
//The first string in the array
string string1 = strings[0];
//The first letter of the first string
char char1 = string1[0];
//The above is the same as:
char char1Again = strings[0][0];
In the line above, the first square bracket operator returns the first string in the array. The second square bracket operator is then applied to that string, which returns the first character of that string.
This works because both arrays and Strings (which are really arrays themselves deep down) implement the square bracket operator to access their internal elements by index.
Technically, in a convoluted way, you could call this a matrix, but "2D array of characters" would be more appropriate.
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.
I am writing a C++ function that is supposed to duplicate an array of chars by copying each element character-by-character into a new array. Ideally, if I make the statements
char* a = "test";
char* b = copyString(a);
then both a and b should contain the string "test." However, when I print the copied array b, I get "test" plus a series of nonsense characters that seem to be the pointer. I don't want those, but I can't figure out where I'm going wrong.
My current function is as follows:
char* copyString(char* s)
{
//Find the length of the array.
int n = stringLength(s);
//The stringLength function simply calculates the length of
//the char* array parameter.
//For each character that is not '\0', copy it into a new array.
char* duplicate = new char[n];
for (int j = 0; j < n; j++)
{
duplicate[j] = s[j];
//Optional print statement for debugging.
cout << duplicate[j] << endl;
}
//Return the new array.
return duplicate;
}
For the purposes of understanding certain aspects of C++, I cannot use string libraries, which is where other answers I have found have fallen short in this case. Any help with this problem is greatly appreciated.
EDIT: I though my stringLength function was fine - perhaps I was wrong.
int stringLength(char* s)
{
int n;
//Loop through each character in the array until the '\0' symbol is found. Calculate the length of the array.
for (int i = 0; s[i] != '\0'; i++)
{
n = i + 1;
}
//Optional print statement for debugging.
// cout << "The length of string " << s << " is " << n << " characters." << endl;
return n;
}
You need to copy the 0 too. That's what a C-style string is, a null-terminated character array.
Really, all you need to do is add one to the length:
int n = stringLength(s) + 1; // include the '\0'
And then everything else will account for itself - you'll allocate an array of sufficient size, and copy the '\0' in your loop too.
My code basically is to list ASCII codepoints of a string that is input, my following code is simple, here:
#include <iostream>
#include <string.h>
using namespace std;
int main() {
char str[20];
int result[20];
cin >> str;
for(int i = 0; i != strlen(str); i++) {
result[i] = (int)i;
}
for(int i = 0; i != 20; i++)
cout << result[i] << ", ";
}
when I run it, no matter what the input it outputs a pile of gibberish like undefined memory like so:
0, 1, 2, 3, 4, 5, 1, -1217349408, -1220040795, -1220041307, -1076427112, 134514781, -1218903292, 134519344, -1076427096, 134514004, -1217411568, 134519344, -1076427048, 134514681,
Am I missing something simple in how I append each integer to the array?
Just note this is a simple example, my input will not be larger than 20 characters.
EDIT Typo in my result.. cin>>result was cin>>str
This loop will iterate a number of times equal to the length of 'str'. That is, it will iterate once for each character in 'str', and stop at the 'null terminator' (char value of 0) which is how c strings are ended. In each loop, the value of 'i' is the loop number, starting at 0 - and this is the value you assign to that index in the results array.
for(int i = 0; i != strlen(str); i++) {
result[i] = (int)i;
}
So for example, for a string of length 5, you will assign the values '0, 1, 2 ,3, 4' to the result array at those indexes, respectively. The other values in the result array are not assigned - and so could hold any value (generally, whatever was in that bit of memory before you started using it). If your string is longer than 20 characters, you're in trouble, because you will start trying to access the array at index 20 and beyond, which is not memory that belongs to your program.
This loop prints out all the values in the 'result' array, from the value at index 0 to the value at index 19:
for(int i = 0; i != 20; i++)
cout << result[i] << ", ";
So it will print the initialised values, and, if the string was less than 20 characters long, the uninitialised values as well.
At a minimum, to start getting anything like the results you're after, you want to change
result[i] = (int)i;
to
result[i] = str[i];
but as mentioned by others, and to escape some of the memory access issues I mentioned above, it would be much better if you use an iterator to get the character values.
for(string::iterator i = str.begin(); i != str.end(); i++)
// access char here using '*i'
strlen(str) will give you an undefined output, because you haven't initialised the contents of str[].
Essentially, you failed to correctly initialize the string and you didn't check that it was the correct size. Correct code:
#include <iostream>
#include <string> // NOT <string.h>, <string>
int main() {
std::string str;
std::cin >> str;
std::cin.ignore();
for(std::string::iterator it = str.begin(); it != str.end(); it++) {
std::cout << (int)(*it);
if (it + 1 != str.end())
std::cout << ", ";
else
std::cout << "\n";
}
std::cin.get();
}
You have 3 problems:
You didn't initialise str with a proper string, thus strlen will return an unpredictable value.
You initialise the first strlen(str) positions of result, but later you print it until the index 20. You should use the same condition on both loops.
You should definitely use std::string and its iterator.
You've not initialized str and you are taking its strlen
When you did
cin >> result; // this does not even compile!!!
I guess you meant
cin >> str;
Its not clear what you are trying to do. But you can try this to get some meaningful result:
char str[20];
int result[20] = {0};
cin >> str;
...// rest all unchanged.
stlen( str ) will give the number of characters before the null terminator.
This means that only strlen(str) integers are valid. The rest are uninitialized.
Also: have a look at std::transform. You can avoid the temporary array of integers to achieve the same, or transform right into one.
int to_codepoint( char c ) { return (int) c; }
// ...
char cs[] = "abcd";
std::transform( cs, cs+strlen(cs)
, std::ostream_iterator<int>( std::cout, ", " ), to_codepoint);
// or transform into an array:
int is[ 1000 ]; // 1000 enough?
std::transform( cs, cs+strlen(cs)
, is, to_codepoint );
(test code at codepad.org)
I'm a beginner and i need to ask a question..
I wrote this small code that accepts a string from the user and prints it..very simple.
#include <iostream>
using namespace std;
int main()
{
int i;
char *p = new char[1];
for(i = 0 ; *(p+i) ; i++)
*(p+i) = getchar();
*(p+i) = 0;
for(i = 0 ; *(p+i) ; i++)
putchar(*(p+i));
return 0;
}
when i enter any string..like "stack overflow" for example..it will print "sta" and drop the rest of the string. I know it's an easy one to solve but since I've just started i can't understand what's wrong here . Thanks in advance .
There are several problems with this code. First, you have a buffer overflow, because char *p = new char[1] allocates only one character for storage. This is exceeded when i > 0. Next, your first loop will keep going until it reaches a point in unallocated memory (undefined behavior) that has a value of zero. This just happens to be after the third value in your case. You probably wanted something more like *(p+i-1) == 0 to give "the last character read meets some condition." Finally, you're allocating memory with new[] and not properly deallocating it with a matching delete[].
Consider using std::cin and std::string for much safer and correct code:
#include <iostream>
#include <string>
int main(int, char**) {
std::string s;
std::cout << "Enter a string: ";
std::cin >> s;
std::cout << s << std::endl;
}
Here is some code along your lines that seems to work. I'm sure there are better (and more C++-ish) ways to do this...
#include <iostream>
using namespace std;
#define MAXLEN 80
int main()
{
int i=0;
char c;
char *p = new char[MAXLEN + 1]; // 1 char will not be sufficient
do // Doing this with a for loop would be unreadable
{
c = getchar();
*(p+i) = c;
i++;
} while( c != '\n' && i < MAXLEN ); // Check for a newline. How do you enter the zero with a keyboard?
*(p+i) = 0; // Ensure that the last character is zero
for(i = 0 ; *(p+i) ; i++) putchar(*(p+i)); // This is OK but difficult to read
delete [] p; // Don't forget this
return 0;
}
The fact that your program does anything is just luck; what stops *(p+i) from being \0 to begin with? It's weird that you're using getchar() and putchar() in a C++ program, too. What's the story behind this program?
If you read into memory, be sure that you allocate enough. new char[1] creates an array of only one char, but you are reading more then that. A simple temporary fix would be to simply allocate more, say new char[255].
Other notes:
you never delete the memory you allocated: delete[] p;
you should check wether you read as much characters as your buffer can hold: for(..;.. && i<bufferSize;..)
the condition in the first loop always checks the next character, not what you just read
*(p+i) is equivalent to p[i], which is more readable
why read and write only one character at a time?
why not use iostreams (std::in, std::out) and std::string as you are using C++?
you only allocate space for one character but you try to put many chars in it.
Is this homework? if so please tag it as such. Are you allowed to use STL?
If so then use std::vector instead on new char[1];
EDIT:to do it without any fiddly bits or STL
const int MAX = 100;
char *p=new char[MAX];
for(i = 0 ; *(p+i) && i < MAX ; i++)
*(p+i) = getchar();
probably some out by ones - left as exercise