Creating an array of characters (user-input) through recursion - c++

I'm creating a program (whose functions must be recursive) which accepts a series of characters from the user, terminated by a period, and displays the characters backwards on the screen. A sample run should give:
Enter a character: H
Enter a character: i
Enter a character: .
iH
I made a function that reverses an array which takes a character array and its size as parameters.
void print_backwards(char a[], int size){
int i = size-1;
cout << a[i];
i--;
if(i >= 0){
print_backwards(a, i);
}
}
I have a problem, however, with initializing the character array using recursion. How can I solve this problem?

This sounds like a homework problem, so I'm not going to solve the problem for you. However, I can give you a push in the right direction.
Make a function that takes a character array by reference and an offset.
On the first call of the function, give it an offset of zero and pass it the empty array.
The function itself should read a single character from the user.
If the character is a ., write a null byte to the current position and return the current offset, else, write the supplied character to the current position, then call the function again with offset+1.
The function will return the length of the input.
The function body will look something like
// Get character from user
if ( c == '.' ) {
input[offset] = '\0';
return offset;
} else {
input[offset] = c;
return thisFunction(input, offset+1);
}

Related

Trying to read a single character at a time into an array of indefinite size

I am a CS student working on a c++ project. We have been instructed to declare a struct and use it to read in an array of chars and keep a tally of how many letters are used in the string. We are not allowed to use a string; it MUST be an array of our declared struct.
The input must be as long as the user wants; the code has to be able to accept new lines of input and be terminated by '.'
I'm really struggling here. I don't even know where to begin. I've thrown together some code as best-guess for what to do, but it crashes after pressing "." then enter, and I don't know why.
//declare struct
struct data
{
int tally = 0;
char letter;
};
//size of string to read in at a time
const int SIZE_OF_CHUNK = 11;
int main()
{
//input chunk of struct
data input[SIZE_OF_CHUNK];
int placemark,
length;
cout << "Enter sequence of characters, '.' to terminate:" << endl;
do
{
for (int index = 0; (input[index].letter != '\0') && (input[index - 1].letter != '.'); index++)
{
cin >> input[index].letter;
placemark++;
}
//I intend to put something here to handle if the code
needs to read in another chunk, but I want to fix the crashing
problem first
}
while (input[placemark].letter != '.');
//print out what was read in, just to check
for (int index = 0; input[index].letter != '\0'; index++)
{
cout << input[index].letter;
}
return 0;
}
I've tried looking up how to read in a single character but haven't found anything helpful to my circumstances so far. Any tips on what I'm doing wrong, or where I can find helpful resources, would be very much appreciated.
Are you sure you must use a declared struct?
If you just want to count the number of times a character has appeared, you don't need to store the character; you just need to store the number of times it appeared. So just unsigned lettersCount[26], and each index maps to a letter (i.e. index 0 means a, index 1 means b). Whenever a letter appears, just increase the count of that index.
You can map a letter to the index by making use of ASCII. Every letter is represented by a decimal number that you can look it up at ASCII table. For example, the letter a is represented by the decimal value 97, b is 98 and so on. The number increases successively, which we can make use of. So if you want to map a letter to an index, all you need to do is just value - 97 or value - 'a'. For example, if you read in the letter a, take away 97 from that and you'll get 0, which is what you want. After getting the index, it's just a simple ++ to increment the count of that letter.
Regarding the treatment of uppercase and lowercase (i.e. treat them the same or differently), it'll be up to you to figure it out how to do it (which should be fairly simple if you can understand what I've explained).

strcpy() is not copying properly c++

Recently I made a program, it has a character array board[8][8][2];
It is basically meant to be a 8X8 board which can store '2' lettered strings. I am not providing the complete code.
But here is the problem.
for (j = 0; j < 8; j++) {
strcpy(board[1][j], P[j].sym);
}
cout << board[1][1] << endl;
Here P[1].sym="P1" and P[0].sym="P0" and P[2].sym="P2"
Therefore P[j].sym is basically a two letter string and board[1][j] should also be a two letter string.
But the output for
cout << board[1][1] << endl;
is given as P1P2P3P4P5P6P7
and the output for
cout << board[1][0] << endl;
is given as P0P1P2P3P4P5P6P7
For
cout << board[1][5] << endl;
P5P6P7 is the output.
To remove any doubt the whole board[8][8][[2] is already initialised
and all of P[j].sym are already initialised.
If it helps here is the code for the initialisation of P:
#include <iostream>
#include <string.h>
using namespace std;
class Game
{
public:
char board[8][8][2];
char *****possibilities;
};
class Pawn : virtual public Game {
public:
char sym[2];
int possiblec[4][2];
Pawn() { }
Pawn(int i) {
char a[2];
a[0] = 'P';
a[1] = (char)(i + 48);
strcpy(sym, a);
}
};
And here somewhere else in the program I did
Pawn P[8];
It calls the constructor and then later on I called the parameterised contructor explicitly.
for (int i = 0; i < 8; i++) {
P[i] = i;
}
After this I checked for different values of P[j].sym and all of them return the perfect values I wanted.
But not when I'm using strcpy() What is the problem here. This program is just a practice program to get a hang of it.
Character arrays in C++ ( and C ) are terminated with a Null character ('\0' ) . So, even if you need to store just two characters in your string, you must have an extra space to store the Null character.
A character array which does not terminate with a Null character can lead to a lot of other problems. It is a wrong practice.
If your character array does not terminate with a Null character, you will get a lot of problems when you call functions such as strcpy() , strcat() , etc...
So, you should change
char board[8][8][2]
to
char board[8][8][3]
And if you have any other strings just like this one, then leave one extra space in them as well.
The reason your code behaved as such is because you got lucky.
Functions such as strcpy() , strcat() all continue to copy ( or append ) until they encounter a Null Character ( which is numerically equal to zero ). So, it continues to do so until the Null character is encountered. But if there is no Null character, then you will most probably get Undefined Behavior. In your case, you just got lucky.
I will show you a brief working of strcpy() ( from here )
char * strcpy(char p, const char * q) {
while (*p++=*q++);
//there's also a return p; statement at the end
}
That is the function.
the while loop executes until it encounters false, and the equivalent for false is 0. So, when it encounters a Null character ( which is also numerically equal to 0 ), the while loop terminates and the copying is complete, and the function ends. So, if there is no Null character at the end, it will give you undefined Behavior.
You can refer man for more info about them
You should always reserve one extra character because strings in C and C++ are null terminated, which that they need one extra character to sign the end of the string.
So, please, change
board[8][8][2]
to
board[8][8][3]
as well as sym[2] to sym[3], a[2] to a[3] (generally add one to the length of all strings) and try again.
By looking at the manual pages for strcpy:
Copies the C string pointed by source into the array pointed by
destination, including the terminating null character (and stopping at
that point).
This means that that function will stop only when it encounters the null character. That's why it would fail if there wasn't any present. But, by setting one character at a time, there's obviously no such problem visible (it will become visible later on, if you try to execute a function that stops only when it encounters a null character and there are plenty of them).
Strings are null ('\0') terminated in C++. When you pass in an character array to printf it stops printing at the null character. I'm guessing the only reason it stopped printing at P7 is because you got lucky and the next memory location happens to be storing Null. You need to make your char arrays at least 1 character longer than the string you want to store.

capitalizing characters, how toupper works?

I need to use a character array and take the characters in the array and capitalize and lower case them as necessary. I was looking at the toupper and its example, but I'm confused about how this works. Looking from the example given on cplusplus.com I wrote
int main(){
int i = 0;
char str[] = "This is a test.";
while(str[i]){
putchar(toupper(str[i]));
i++;
}
for(int i = 0; i < 15; i++){
cout << str[i];
}
}
and there are two things I don't understand about this. The first is that without the cout at the bottom, the program prints out THIS IS A TEST. Does putchar print to the screen? (the use of putchar is not explained on the example). But my second more important question is why does the cout at the bottom still print out This is a test.? Does it not change the chars in str[]? Is there another way I should be doing this (keeping in mind I need to use character arrays)?
Yes, putchar() prints a character to the program's standard output. That is its purpose. It is the source of the uppercase output.
The cout at the bottom of the program prints the original string because you never modified it. The toupper() function doesn't -- indeed can't -- modify its argument. Instead, it returns the uppercased char.
putchar writes a single character to output: http://www.cplusplus.com/reference/cstdio/putchar/
As a result, the first while loop converts each character from str one at a time to upper case and outputs them. HOWEVER, it does not change the contents of str - this explains the lower case output from the second loop.
Edit:
I've expanded the first loop:
// Loop until we've reached the end of the string 'str'
while(str[i]){
// Convert str[i] to upper case, but then store that elsewhere. Do not modify str[i].
char upperChar = toupper(str[i]);
// Output our new character to the screen
putchar(upperChar);
i++;
}

C++ Adding any character inside string array

This is my first time I ask , so please can help. My question is how can I Add any character between any string like , mean adding dot after every c (small letter) , but I dont want to use any function , I want to write my own void function with passing only one parameter that should be an array of char , Can help please?
I learn how to check every character in the string with
while(*p!='\0')
{
/// What should I write here to check if there is any dot , then add after it
/// a small c
p++;
}
If you are going to do it the C way, I'd suggest you try something like this:
void adjust_string(char*output_p, int output_space, const char* input_p)
{
//while (there is still input left, and room in output buffer) {
while (*input_p!='\0' && output_space>2) {
//copy input character to output
//update the output pointer
//update the amount of room left in the output buffer
//if (its a special character) {
//add the extra character to output
//update the output pointer
//update the amount of room left in the output buffer
}
//update the input pointer
input_p++;
}
//null-terminate the output string
}
In the function that calls this function, you need to provide an array for the output to be placed into and specify its length, so you can't get a buffer overrun.
Note: in checking for room in the output buffer you need to take into account the possibility of adding the extra character in, and the room for the terminating null character.

ASCII and isalpha if statement issue

I am writing a program that takes a user inputted character, such as A, and a user inputted number, such as 7. The program checks the validity of the character, if true runs thru till it gets to this loop inside of a function. I am using ascii decimal for this loop inside of a function. This loop needs to check isalpha and if it is run the code inside the {}'s, it's doing that correctly. The else is not working the way I want and am not sure how to correct it. I need the else (is not alpha) to add a 1 back to the counter in the loop and increase the ascii by 1. If I run it as so, it gives off a retry/ignore/abort error. If I run it without the num++; it runs and stops after the loop ends. So, if you put in a Z and choose 3, it runs thru the loop 3 times and outputs just a Z. Any thoughts on how to fix this?
I need it to output something like: Input: Z Input: 4 it should output: Z A B C to the screen. It needs to ignore other ascii non alpha characters.
Thanks
string buildSeries(char A, int num)
{
//builds the output with the info the
//user inputted
stringstream str1;
string outted;
int DeC=(int)A, i = 0;
//loop builds the output
for(i=0;i<num;i++)
{
if (isalpha(DeC))
{
//converts the decimal to a letter
str1<<(char)DeC;
//adds a space
str1<<" ";
//increases the decimal
DeC++;
}
else
{
num++;
DeC++;
}
}
//builds the sstream and puts it in
//variable "outted"
outted = str1.str();
return outted;
}
If you need to loop back to 'A' at Z change your DeC++ to
if DecC == 'Z'
DecC = 'A'
else
DecC++;
Or you could get fancy and use the modulus operator
Edit
I think the problem may be that this stringstream insertion operator, >>, doesn't have an overload that handles a char. It's converting the char to a short or an int then inserting it. Try using string::append(size_t size, char c) instead. That should handle inserting a char.
That is replace you calls to str1<<(char)DeC; with outted.append(1, (char)DeC) and remove your use of the string stream
What is DeC? The phrase "ascii list" makes me suspect it's a 'C' string, in which case you are calling isAlpha() on the pointer not on the value in the string.
edit: If for example you have
char DeC[40];
// read in a string form somewhere
// DeC is a pointer to some memory it has a value of a 32 or 64bit number
if ( isAlpha(DeC) {
// what you might have meant is
if ( isAlpha(*DeC) { // the character value at the current position in DeC