Trying to reverse a C string - c++

I cannot use any c functions except strlen(), and I also cannot use strings. I have been at this for an unfortunate amount of time. I keep getting weird characters as part of the output. i.e question marks and essentially weird alt codes is what it looks like.
#include <iostream>
#include <cstring>
using namespace std;
int lastIndexOf(const char*, char[]);
void reverse(char*);
int replace(char*, char, char);
int main() {
int i = 0, count = 0, counter = 0, SIZE = 100;
char charArray[SIZE];
cout << "Enter a string of no more than 50 characters: ";
cin.getline(charArray, SIZE);
reverse(charArray);
}
void reverse(char s[])
{
int n = 100;
for (int i = 0; i < n / 2; i++) {
swap(s[i], s[n - i - 1]);
cout << (s[i]);
}
}
I have tried several different things, swap function, using pointers to manually swap them with a temp variable. So I went to the internet to see what other people did, but to no avail. I am convinced there is a simple solution.

The function uses a magic number 100
int n = 100;
though in main there is a prompt to enter no more than 50 characters.
cout << "Enter a string of no more than 50 characters: ";
You need to calculate the length of the passed string by using the standard C function strlen.
The function can look the following way
char * reverse( char s[] )
{
for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
{
std::swap( s[i], s[n-i-1] );
}
return s;
}
Pay attention to that variable length arrays is not a standard C++ feature.
You should write
const size_t SIZE = 100;
char charArray[SIZE];

Related

How to count characters in a C_String in C++?

I'm a new Computer Science student, and I have a homework question that is as follows:
Write a Function that passes in a C-String and using a pointer determine the number of chars in the string.
Here is my code:
#include <iostream>
#include <string.h>
using namespace std;
const int SIZE = 40;
int function(const char* , int, int);
int main()
{
char thing[SIZE];
int chars = 0;
cout << "enter string. max " << SIZE - 1 << " characters" << endl;
cin.getline(thing, SIZE);
int y = function(thing, chars, SIZE);
cout << y;
}
int function(const char *ptr, int a, int b){
a = 0;
for (int i = 0; i < b; i++){
while (*ptr != '\0'){
a++;
}
}
return a;
}
First of all welcome to stackoverflow ye0123! I think you are trying to rewrite the strlen() function here. Try giving the following link a look Find the size of a string pointed by a pointer.
The short answer is that you can use the strlen() function to find the length of your string. The code for your function will look something like this:
int function(const char *ptr)
{
size_t length = strlen(ptr);
return length;
}
You should also only need this function and main.
Edit: Maybe I misunderstood your question and you are supposed to reinvent strlen() after all. In that case, you can do it like so:
unsigned int my_strlen(const char *p)
{
unsigned int count = 0;
while(*p != '\0')
{
count++;
p++;
}
return count;
}
Here I am comparing *p from '\0' as '\0' is the null termination character.
This was taken from https://overiq.com/c-programming-101/the-strlen-function-in-c/

Creating strings by splitting a char array

As part of my homework assignment, I have to split a char[] by its indices. So for example, the main function looks like:
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size;
cout << "Enter the size of the part: ";
cin >> split_size;
int size = sizeof(str) / sizeof(str[0]);
SplitString(str, split_size, size);
int wait;
cin >> wait;
return 0;
}
Then using the function SplitString, the first x elements are printed, new line, then the next.
My first idea, was to use two for loops. One loops through the splits (i.e. if there are 4 splits, the range on this loop is 0 to 3), then the second loops through the split itself, iterating over the array elements.
My SplitString() function looks like this:
void SplitString(char str[], int split_size, int size) {
int parts = size / split_size;
for (int i = 0; i < parts; i++) {
for (int j = 0; j < split_size; j++) {
j = split_size * i;
cout << str[j];
}
cout << endl;
}
}
Is there an easier way to do this? I know in Python, you can use the arr[1:] to grab a range of elements from the array. Is there anything similar in C++? Is there some flaw in my logic? Is there something wrong with my code?
cout comes with a write function that takes a pointer and a size argument.
for (int i = 0; i < parts; i++) {
cout.write (str+i*split_size, split_size)
cout << endl;
}
Note that the code above does not check if the string is actually long enough. If the total size is not equal the split_size times a whole number, you will have to add an additional check.
Also, note that this:
int size = sizeof(str) / sizeof(str[0]);
can be written as:
int size = sizeof(str);
instead because the size of a char is always 1.
You can use std::string for this. Alternatively, if your compiler supports C++17, you can use std::string_view as the first argument of SplitString to avoid unnecessary copying.
#include <algorithm>
#include <iostream>
#include <string>
void SplitString(std::string s, std::size_t split_size)
{
while(!s.empty())
{
auto size = std::min(split_size, s.size());
std::cout << s.substr(0, size) << '\n';
s = s.substr(size, std::string::npos);
}
}
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size = 5;
SplitString(str, split_size);
return 0;
}
Live example.

Outputting to console from Char Array

im creating a hangman game that has to use CHAR and not strings. I was wondering how i would choose a single random word form a Char array and display it to the console as a symbol e.g. ****** instead of the word. My current array; Thank you.
char words [6][10] =
{
"Pistachio",
"Avocado",
"Salami",
"Bologna",
"Christmas",
"Giraffes",
};
This is what i have so far (i know it not much im a bit confused)
cout <<"Test " <<words <<endl;
and that just out put a random number ??
To output a cstring from an array of cstrings you need to provide the index of that string.
cout <<"Test " <<words <<endl;
Will just print the address of the first element of the array since that is what an array name is reduced to. So the correct way to display from the array is:
cout <<"Test " <<words[indexOfTheStringYouWant] <<endl;
words is a char** an array of char[10]. The << operator knows how to print simple types (int, float), std::string and char *, but not char ** arrays nor pointers to C strings (char arrays). So it only print the address of the array of char *. char[10]
I think that what you want is :
for (int i=0; i< sizeof(words)/sizeof(char *); i++) cout << words[i] << " ";
cout << endl;
If I have understood correctly what you need is the following
#include <iostream>
#include <algorithm>
#include <numeric>
#include <cstdlib>
#include <ctime>
int main()
{
const size_t N = 6;
const size_t M = 10;
char words[N][M] =
{
"Pistachio",
"Avocado",
"Salami",
"Bologna",
"Christmas",
"Giraffes",
};
size_t index[N];
std::iota( index, index + N, 0 );
std::srand( ( unsigned int )std::time( nullptr ) );
std::random_shuffle( index, index + N );
for ( size_t i = 0; i < N; i++ ) std::cout << words[index[i]] << std::endl;
return 0;
}
The program output might look like
Giraffes
Bologna
Pistachio
Avocado
Salami
Christmas
I think you are looking for this:
#include<cstdlib>
int v;
for(int i=0; i<10; i++)
{
v = rand() %6;
printf("%s\n", words[v]);
}

C++ qsort issues

I wrote the following to try to use the qsort() function. My goal is to input several lines of text and print an alphabetical listing of each word. This code crashes every time I run it and i am not sure as to why or how to fix it. I also need to add something to count the number of times a word occurs and print that as well but I an mot too sure how to do that. Any advice would be very helpful. Thanks!
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
struct to_lower
{
int operator() ( int ch )
{
return tolower ( ch );
}
};
int compare (const void * a, const void * b)
{
//return ( *(int*)a - *(int*)b );
return (strcmp(*(const char **)a, *(const char **)b));
}
int main()
{
string list[900];
int nLength;
int i=0, q=0;
string nTemp;
int word[900];
cout
<< "Enter some lines of text "
<< "(Enter Ctrl-Z on a line by itself to exit)\n"
<< endl;
while ( !cin.eof() )
{
cin >> list[i];
transform(list[i].begin(), list[i].end(), list[i].begin(), to_lower());
word[q]=1;
if (list[i]==list[i-1])
{
word[q]=+1;
}
i++;
}
nLength = i;
cout << "The sorted words would be:\n";
qsort(list, nLength, sizeof list[0],&compare);
int n;
for (n = 0; n < nLength; n++)
{
cout <<" \n"<< n << list[n]<< word[n];
}
return 0;
}
std::string is not a char* as your qsort compare function pretends. Also, you should never use qsort with C++ objects. qsort does not know about objects and won't call copy constructors and may damage the internal structure.
When i=0, using list[i-1] is a bug.
You need to count your duplicate words after sorting or you have no guarantee that duplicates are next to each other.

Passing 2D arrays to function

I am trying to make an ASCII world, however I am unable to pass 2D arrays between functions. It is a 20 x 20 array, and I want to place houses randomly across it. The array won't pass like I want it to, and my tutorial told me that global variables are evil, so a solution without those would be great.
using namespace std;
void place_house(const int width, const int height, string world[width][length])
{
int max_house = (width * height) / 10; //One tenth of the map is filled with houses
int xcoords = (0 + (rand() % 20));
int ycoords = (0 + (rand() % 20));
world[xcoords][ycoords] = "#";
}
int main(int argc, const char * argv[])
{
srand((unsigned)time(NULL));
const int width = 20;
const int height = 20;
string world[width][height];
string grass = ".";
string house = "#";
string mountain = "^";
string person = "Å";
string treasure = "$";
//Fill entire world with grass
for (int iii = 0; iii < 20; ++iii) {
for (int jjj = 0; jjj < 20; ++jjj) {
world[iii][jjj] = ".";
}
}
place_house(width, height, world);
for (int iii = 0; iii < 20; ++iii) {
for (int jjj = 0; jjj < 20; ++jjj) {
cout << world[iii][jjj] << " ";
}
cout << endl;
}
}
Try passing string ** instead of string[][]
So your function should be declared like this:
void place_house(const int width, const int height, string **world)
and then you access your array usual way.
Remember to handle bounds correctly (probably you want to pass them together with array).
edit:
This is how you might achieve what you need:
#include <string>
#include <iostream>
using namespace std;
void foo (string **bar)
{
cout << bar[0][0];
}
int main(void)
{
string **a = new string*[5];
for ( int i = 0 ; i < 5 ; i ++ )
a[i] = new string[5];
a[0][0] = "test";
foo(a);
for ( int i = 0 ; i < 5 ; i ++ )
delete [] a[i];
delete [] a;
return 0;
}
edit
Another way of achieving what you want achieve (that is passing static array to a function) is to pass it as one dimmensional array and then use C-like way of accessing it.
Example:
#include <string>
#include <iostream>
using namespace std;
void foo (string *bar)
{
for (int r = 0; r < 5; r++)
{
for (int c = 0; c < 5; c++)
{
cout << bar[ (r * 5) + c ] << " ";
}
cout << "\n";
}
}
int main(void)
{
string a[5][5];
a[1][1] = "test";
foo((string*)(a));
return 0;
}
This little example is nicely described here (see Duoas post).
So I hope this will describe different ways of doing similar thing. This, however, does look quite ugly and probably is not the best programming practice (I would do everything to avoid doing that this way, dynamic arrays are quite nice you just need to remember releasing them).
Since your array has compile-time known dimensions, you could use templates to detect it like this:
template <std::size_t W, std::size_t H>
void place_house(string (&world)[W][H])
{
int max_house = (W * H) / 10; //One tenth of the map is filled with houses
int xcoords = (0 + (rand() % 20));
int ycoords = (0 + (rand() % 20));
world[xcoords][ycoords] = "#";
}
// ...
place_house(world); // Just pass it
Note, that this trick will not works with dynamically allocated arrays. In that case, you should use something like std::vector.
You don't need to size the parameter in the declaration and can't because the [][] syntax requires compile time constants.
Replace with string world[][] and it should work.
If it doesn't then use string[]* world (an array of array of strings is actually an array of pointers to an array of string)
I hope this helps, my C++ is becoming increasingly rusty.