Is this reverse string code correct? - c++

This code works for me when I run it on my IDE, but it doesn't work on the website that has the exercise. I get a segmentation fault. So is this code correct? Did I make a mistake?
#include <iostream>
#include <string>
using namespace std;
string FirstReverse(string str) {
for (int i = 0, back = str.size()-1; i != back; ++i, --back)
{
char c = str[back];
str[back] = str[i];
str[i] = c;
}
return str;
}
int main() {
cout << FirstReverse("hello");
return 0;
}
Also, what's the best way to do this?

Your index only needs to reach half of the length, and that way we ensure that the swap between a pair only happens once:
for (int i = 0; i < str.size() / 2 ; i ++)
{
char c = str[str.size() - 1 - i];
str[str.size() - 1 - i] = str[i];
str[i] = c;
}

If you change the loop condition to "i <= back" then it won't cause segmentation fault. It is because when size-1 is even , i & back will never become equal. Thus loop will keep on going without breaking & attempt to access string member outside the string.

Just change your condition from != to <= and it will be solved.

Related

Make floor pattern

How do i make this?
image of my homework
note: Batasan means limitaion and Contoh means example
So, my professor wants me to do make output the same size horizontal and vertically in pattern shown in the image
I dont know what to do, but the best i can make is this:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
const char * array1[4];
const char * array2[4];
array1[0] = "O", array1[1] = ">", array1[2] = "X", array1[3] = "<";
array2[0] = "v", array2[1] = "/", array2[2] = "^", array2[3] = "\\";
cin>>n;
for(int i = 1; i <= n; i++){
if (i%2 != 0){
for(int j = 0; j <=n; j++){
cout << array1[j];
}
cout<<"\n";
} else if (i%2 != 0) {
for(int j = 0; j <=n; j++){
cout << array2[j];
}
cout<<"\n";
}
return 0;
}
}
I dont know if array is necessary or not.
If you guys have any suggestion about my program feel free to give me some.
This is my first time asking in this web and im sorry if my post and english are terrible
Thanks in advance:)
We are here to help.
I will first show you the problems in your code and then make a proposal on how to make it better.
So, let us first check your code:
#include<bits/stdc++.h> is a non C++ compliant compiler extension. It should never be used. On my machine, it does not compile.
using namespace std; should not be used. It is better to always use full qualified names. This will avoid name clashes from different scopes or namespaces
Variables should have meaningful names. One character variables are in most cases not that good
All variables should be initialized during definition
C-Style arrays should not be used in C++. Always use a specialized STL container like std::vector or std::array
In C++ we use std::string for strings and not char[] or char *
Array indices in C/C++ start with 0. If you use <= in the end condition of a for loop, you will access an element one past the end. This is a severe out of bound error. You do that in you for loop with the 'j'
There is anyway a severe out of bound bug here. You access array[j] and j might be 4 or bigger. That is a bug and must be corrected. You can simply do a modulo devision % by 4. Then you do never exceed the 4. it will then always be 0,1,2,3,0,1,2,3,0,1,2,3 . . .
You should write as much as possible comments
If we correct all this findings, then we could come up with:
#include <array>
#include <iostream>
constexpr size_t NumberOfLinePatterns = 2;
constexpr size_t NumberOfElementsPerLinePattern = 4;
using Pattern = std::array<std::array<char, NumberOfElementsPerLinePattern>, NumberOfLinePatterns>;
// If you do not yet know the std::array. Then uncomment the following and
// remove on opening and closing curly brace in the initialization below
// using Pattern = char[NumberOfLinePatterns][NumberOfElementsPerLinePattern];
Pattern pattern{{
{'O','>','X','<'},
{'v','/','^','\\'}
}};
int main() {
// Get number of rows and columns to print
unsigned int numberOfElements{}; std::cin >> numberOfElements;
// Now, for all rows and columns
for (unsigned int row{}; row < numberOfElements; ++row) {
for (unsigned int column{}; column < numberOfElements; ++column) {
// Print the selected character
std::cout << pattern[row % NumberOfLinePatterns][column % NumberOfElementsPerLinePattern];
}
std::cout << '\n';
}
return 0;
}

First try on string array not working. Is there something I don't know?

I just tried to use string array for the first time, and I experienced consistent crashes. It's supposed to draw a shrinking circle. Did I forget to add some important line, or is there an error in the existing code? I'm a beginner, so please don't be too mean..
#include <iostream>
#include <string>
#include <cmath>
#include <windows.h>
using namespace std;
int main() {
for (int h = -10; h < 10; h ++)
{
int r = abs(h);
string gps[20];
for (int i = -10; i < 10; i ++)
{
for (int j = -10; j < 10; j ++)
{
if (i*i + j*j <= r*r && i*i + j*j >= (r-1)*(r-1))
gps [j+10][i+10] = char (219);
else
gps [j+10][i+10] = ' ';
}
}
for (int i = 0; i < 20; i ++)
{
for (int j = 0; j < 20; j ++)
cout << gps[i][j];
cout << '\n';
}
//system("CLS"); // I know this isn't the best method, but it's the only one i know that works
// By proffesional analysis (cout), i diagnosed the problem to occur right about here
}
return 0;
}
One major issue with your code is that you are writing to the string at an out-of-bounds index here:
//...
gps [j+10][i+10] = char (219);
//...
gps [j+10][i+10] = ' ';
This declaration:
string gps[20];
declares an array of 20 empty strings. Since the strings are empty, you cannot simply write to any position in these string. These strings must already be sized appropriately before writing to a particular location.
What you may need to do is the following:
string gps[20];
for (auto& s : gps)
s.resize(20);
This will resize each string in the array to 20 elements, thus making your loop access valid entries in any of those strings. Writing to an out-of-bounds string position is undefined behavior, where in your case, the program crashes.
Now, will this draw the circle correctly, I am not sure. But this answer focuses on the crash you are getting when running the program.

Hackerrank "Abort Called": I don't know what's wrong[C++]

I was solving a problem from hackerrank in VSCode. I thought I had finally figured out the solution, so I copied it over to the hackerrank compiler. I hit compile and it pops up an "Abort Called" error. Here's the code:
#include <iostream>
#include <bits/stdc++.h>
void printEvenArray(char charArray[], int length)
{
for(int i = 0; i < length; i++)
{
if(i == 0 || i % 2 == 0)
{
std::cout << charArray[b];
}
}
std::cout << ' ';
}
void printOddArray(char charArray[], int length)
{
for(int i = 0; i < length; i++)
{
if(i != 0 && i % 2 != 0)
{
std::cout << charArray[i];
}
}
std::cout << '\n';
}
int main() {
int numOfSubjects, stringLength = 0;
std::cin >> numOfSubjects;
std::string subjectString[numOfSubjects];
char stringToCharArray[stringLength + 1];
for(int i = 0; i < numOfSubjects; i++)
{
std::cin >> subjectString[i];
}
for(int x = 0; x < numOfSubjects; x++)
{
stringLength = subjectString[x].length();
strcpy(stringToCharArray, subjectString[x].c_str());
printEvenArray(stringToCharArray, stringLength);
printOddArray(stringToCharArray, stringLength);
}
return 0;
}
This code compiles fine in VSCode. It gives me the desired outcome, but as soon as I bring it over to hackerrank, it gives an "Abort Called" error. I've read up online that abort called only shows up when either I try to use memory I don't have access to or is read only, or if I use a certain macro, am I'm not using any macros. I'm also relatively knew to C++, and clueless to memory management if that's what the issue is here. I appreciate any help a whole lot.
char stringToCharArray[stringLength + 1];
So, stringToCharArray has length 1. Nothing in the loop changes that. Your strcpy is much longer than one character, so it just overwrites whatever was next in memory. On one compiler you got away with this behavior, but the other (probably deliberately set to look for boundary violations like this) aborted.
Read about https://en.wikipedia.org/wiki/Buffer_overflow.
There are some other improvements you can make. For instance, i+=2 can step through a loop two at a time without checking whether i be odd or even.

Logical error from std string find method and count algorithm

When I was about to solve a project euler problem in C++, this was some of the experimentation code I made. It produced a quite unexpected result, so I solved it in an other programming language. But I really want to understand why this error occured. The part one of the code executes as expected, it does not print AAAA. But in part two, the logically equivalent code (the if statement) executes when the variable s is AAAA. And I have no idea why. I hope I made my problem clear, every answer given is highly appreciated! Thanks :)
Note: i'm using count from <algorithm>
#include <iostream>
#include <algorithm>
using namespace std;
int main (int argc, char** argv) {
string alt = "LOA";
// CODE PART 1
string stringToFind = "AAA";
string df = "AAAA";
if (df.find(stringToFind) == string::npos && count(df.begin(), df.end(), 'L') <= 1) {
cout << df; // this does not print AAAA
}
/* CODE PART 2:
this was an attempt to print out every four length string combination
of the characters L, O, A where strings with three A's in a row and
more than one L were excluded.
*/
for (size_t i = 0; i < 3; i++) {
char c1 = alt[i];
for (size_t iT = 0; iT < 3; iT++) {
char c2 = alt[iT];
for (size_t itr = 0; itr < 3; itr++) {
char c3 = alt[itr];
for (size_t itrI = 0; itrI < 3; itrI++) {
char c4 = alt[itrI];
string s = string(&c1)+string(&c2)+string(&c3)+string(&c4);
if (s.find(stringToFind) == string::npos && count(s.begin(), s.end(), 'L') <= 1) {
cout << s << endl; // this however, does print out AAAA
}
}
}
}
}
return 0;
}
You have written
string s = string(&c1)+string(&c2)+string(&c3)+string(&c4);
You meant:
string s = string(1,c1)+string(1,c2)+string(1,c3)+string(1,c4);
or
string s = string(&c1,1)+string(&c2,1)+string(&c3,1)+string(&c4,1);
In your code, you have invoked the string constructor which takes a pointer to a nul-terminated array of char, but you given it a pointer to a single char. That's going to invoke all sorts of undefined behaviour.
Either invoke the constructor that takes a a counter + a single char or, the one which takes a pointer and a count, and you can tell it there is exactly one character at that address.
Edit There is no constructor which takes a single char. You have to give it a count + char. Which means it's not so pretty.

How to find a char array in another one in c++?

I want to write a code to find a char array in another one and print out place(element) of first occur of first array. I wrote my own code and it works. But it "seems" kind of messy. Does anyone have better idea to rewrite this code?
"only strlen() is allowed. I need to write it by designing loops."
Here's the code
#include <iostream>
#include <string.h>
using namespace std;
const int len = 100;
int main() {
int i, j, k, l;
char a[len]="leonardo" , b[len]="nar";
bool es1 = false, es2=false;
i = 0;
while(i < len && !es1)
{
j = 0;
if(a[i] == b[j])
{
k = i+1;
l = j;
while (k < i+strlen(b) && !es2)
{
j = j+1;
if (a[k] == b[j]) k = k+1;
else es2 = true;
}
if (a[i+strlen(b)-1]==b[l+2] && !es2) es1 = true;
else i = i+1;
}
else i= i+1;
}
cout << endl << "element: " << i;
return 0;
}
By the way this not a real homework. I just make myself ready for a programming exam.
I just find out that the code doesn't work fine if array b[] is shorter than 3 elements. So it seems the code needs major review!
The easy way to do it would be to use std::search:
auto it = std::search(a, a + 8, b, b + 3));
Here, it points to the beginning of the found sequence in a, or to std::end(a) if not found.
This looks like substring search algorithm. You can use any of the recognized algorithms like KMP.
Can you use a string instead of a char array? If so, you can use string::find.
http://www.cplusplus.com/reference/string/string/find/
bool bFound = strA.find(strB)