Insertion of character in an initialized array [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Let the array I have declared be:
char input[] = {'a','l','d'};
Now, I have to insert another character inside this array. Can I insert my character inside this array, or do I have to change the size of the input array and then insert?
Do char input[] = {'a','l','d'} and char input[3]={'a','l','d'} both have the same meaning, or in the first case is the size of array not fixed?
What do I have to do if I want to replace all characters in my array with '3', '.', '1', '4'?

char input[] = {'a','l','d'} and char input[3]={'a','l','d'} do both have same meaning
Yes, they have the same meaning.
now I have to insert an another character inside this array
I have to change the size of the input array
It is not possible to change the size of an array or to insert elements into it. The size of an array remains constant through the lifetime of the array.
can u please tell me what to do to insert new character in the same array
You don't, because you can't.
In C++, I would recommend using the std::string class to represent a character string that can change size. A minimal example:
std::string input = "ald";
input.push_back('i');

If you have
char input[] = {'a','l','d'};
then the array is of size exactly 3, and there's no possibility to store additional characters in it.
You can overwrite:
input[1] = 'n';
but that replaces a character, not insert.
If you declare the array with some extra size, then you have some wiggle room.
char input[10] = {'a','l','d', '\0'};
Now we have room for 10 characters, and null termination to make it a proper string, so we can easily print it:
printf("input = %s\n", input);
This prints "input = ald".
Overwrite a character:
input[1] = 'n';
printf("input = %s\n", input);
This prints "input = and".
Add a character at the end:
input[3] = 'y';
input[4] = '\0'; /* since we just overwrote the old one */
printf("input = %s\n", input);
This prints "input = andy".
Slide some characters to the right, to make room for new ones
for(int i = 4; i >= 2; i--) /* move two characters, and \0, to the right */
input[i+1] = input[i];
input[2] = 'o';
printf("input = %s\n", input);
This prints "input = anody".
Another way to move characters is with memmove:
memmove(&input[4], &input[2], 4); /* move three characters, and \0, two to the right */
input[2] = 'y';
input[3] = 'b';
printf("input = %s\n", input);
This prints "input = anybody".
But this is all very fussy and error-prone. Examples like I've shown can teach you how characters, arrays, and strings work in C, but they're hard to get right, and I wouldn't necessarily recommend that you write code like this to manipulate your own strings.
If you want to replace all characters, it's easy enough, as long as you're sure there's room. Just use strcpy:
strcpy(input, "3.14");
printf("input = %s\n", input);
This prints "input = 3.14".
You have to be careful when calling strcpy, though. The destination array has to be (a) writable and (b) big enough. If you wrote
char input2[3];
strcpy(input2, "3.14"); /* WRONG */
that would be wrong, because input2 is not big enough. And if you wrote
char *input3 = "hello";
strcpy(input3, "3.14"); /* WRONG */
that would be wrong, because input3 is now a pointer, that points to an unnamed array containing the string "hello", and while it's big enough, it's probably an unwritable constant string.

Related

How to pad char array with empty spaces on left and right hand side of the text

I am fairly new with C++ so for some people the answer to the quesiton I have might seem quite obvious.
What I want to achieve is to create a method which would return the given char array fill with empty spaces before and after it in order to meet certain length. So the effect at the end would be as if the given char array would be in the middle of the other, bigger char array.
Lets say we have a char array with HelloWorld!
I want the method to return me a new char array with the length specified beforehand and the given char array "positioned" in the middle of returning char array.
char ch[] = "HelloWorld";
char ret[20]; // lets say we want to have the resulting char array the length of 20 chars
char ret[20] = " HelloWorld "; // this is the result to be expected as return of the method
In case of odd number of given char array would like for it to be in offset of one space on the left of the middle.
I would also like to avoid any memory consuming strings or any other methods that are not in standard library - keep it as plain as possible.
What would be the best way to tackle this issue? Thanks!
There are mainly two ways of doing this: either using char literals (aka char arrays), like you would do in C language or using built-in std::string type (or similar types), which is the usual choice if you're programming in C++, despite there are exceptions.
I'm providing you one example for each.
First, using arrays, you will need to include cstring header to use built-in string literals manipulation functions. Keep in mind that, as part of the length of it, a char array always terminates with the null terminator character '\0' (ASCII code is 0), therefore for a DIM-dimensioned string you will be able to store your characters in DIM - 1 positions. Here is the code with comments.
constexpr int DIM = 20;
char ch[] = "HelloWorld";
char ret[DIM] = "";
auto len_ch = std::strlen(ch); // length of ch without '\0' char
auto n_blanks = DIM - len_ch - 1; // number of blank chars needed
auto half_n_blanks = n_blanks / 2; // half of that
// fill in from begin and end of ret with blanks
for (auto i = 0u; i < half_n_blanks; i++)
ret[i] = ret[DIM - i - 2] = ' ';
// copy ch content into ret starting from half_n_blanks position
memcpy_s(
ret + half_n_blanks, // start inserting from here
DIM - half_n_blanks, // length from our position to the end of ret
ch, // string we need to copy
len_ch); // length of ch
// if odd, after ch copied chars
// there will be a space left to insert a blank in
if (n_blanks % 2 == 1)
*(ret + half_n_blanks + len_ch) = ' ';
I chose first to insert blank spaces both to the begin and to the end of the string and then to copy the content of ch.
The second approach is far easier (to code and to understand). The max characters size a std::string (defined in header string) can contain is std::npos, which is the max number you can have for the type std::size_t (usually a typedef for unsigned int). Basically, you don't have to worry about a std::string max length.
std::string ch = "HelloWorld", ret;
auto ret_max_length = 20;
auto n_blanks = ret_max_length - ch.size();
// insert blanks at the beginning
ret.append(n_blanks / 2, ' ');
// append ch
ret += ch;
// insert blanks after ch
// if odd, simply add 1 to the number of blanks
ret.append(n_blanks / 2 + n_blanks % 2, ' ');
The approach I took here is different, as you can see.
Notice that, because of '\0', the result of these two methods are NOT the same. If you want to obtain the same behaviour, you may either add 1 to DIM or subtract 1 from ret_max_length.
Assuming that we know the size, s, of the array, ret and knowing that the last character of any char array is '\0', we find the length, l, of the input char array, ch.
int l = 0;
int i;
for(i=0; ch[i]!='\0'; i++){
l++;
}
Then we compute how many spaces we need on either side. If total_space is even, then there are equal spaces on either side. Otherwise, we can choose which side will have the extra space, in this case, the left side.
int total_spaces = size-l-1; // subtract by 1 to adjust for '\0' character
int spaces_right = 0, spaces_left = 0;
if((total_spaces%2) == 0){
spaces_left = total_spaces/2;
spaces_right = total_spaces/2;
}
else{
spaces_left = total_spaces/2;
spaces_right = (total_spaces/2)+1;
}
Then first add the left_spaces, then the input array, ch, and then the right_spaces to ret.
i=0;
while(spaces_left > 0){
ret[i] = ' ';
spaces_left--;
i++;
} // add spaces
ret[i] = '\0';
strcat(ret, ch); // concatenate ch to ret
while(spaces_right){
ret[i] = ' ';
spaces_right--;
i++;
}
ret[i] = '\0';
Make sure to include <cstring> to use strcat().

arrays of type char and rand function

I could not phrase the question properly but here it goes: I want to create a random password and that password contains special characters,letter and numbers
so i have decided the ASCII range and assigned them to the password array
everything works properly but when i print it out to the console weird characters pop up that were not in the range.
int main(){
srand(time(nullptr));
char password[15];
int i = 0;
for (i = 0; i < 15; i++)
{
password[i] = (rand() % 89) + 33;
}
cout << password << endl;
return 0;
}
that is the code that causes problem but when i assign the last element to be null value it works properly.
is it because when you create a c type string the last index should always be null?
A string must finish with a string terminator, or it isn't a string. If you omit the terminator, there is no way to know how long the string is. One might assume that since password is const char[15] that the size could be deduced, but in practice, just about everything that works with strings will treat it as a pointer and iterate until a null terminator is found. Since you don't have one, they will iterate past the end of your buffer leading to undefined behavior. Consider using std::string to avoid these concerns. See Null-terminated byte strings.

About pointers and arrays [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include<stdio.h>
#include<stdlib.h>
char *syllable[26] = {"a","bub","cash","dud","e","fud","gug","hash","i","jay",
"kuck","lul","mum","nun","o","pub","quack","rug","sus",
"tut","u","vuv","wack","xux","yuck","zug"};
void Tutnese(char *word, char *newword);
char *letter;
void Tutnese(char *word, char *newword)
{
//clrscr();
for(*letter = 'A'; *letter <= 'Z'; *letter++)
{
letter=syllable;
printf("%c\n",&letter);
}
}
Tutnese is an English language game primarily used by children who use it to converse in
(perceived) privacy from adults (or vice versa)
I am trying to let A="A" B="bub" c="cash" and so on.
I am expecting a result like this.
“computer.” becomes “cashomumpubututerug.”
- “Stony” become “Sustutonunyuck”
but i just start learning c, and i have no idea how to use pointer. I've been keep getting error like assignment makes integer from pointer without a cast
char *letter;
This statement declares a variable named letter, same way as any other statement like char ch; will do.
Now, what's the difference then!!
Well the difference (and similarity) is:
char ch; declares a char variable, i.e. a memory block of size 1 byte is allocated (statically), which you can refer to using ch.
char *letter; on the other hand declares a char pointer i.e. a memory size of 2 or 4 or 8 bytes (depending on compiler) will be allocated (again statically) to store address of a char variable.
Now when you use *letter as lvalue (on Left Hand Side) as you do in for loop, this means you are trying to write to the memory address stored in letter. In your case you never stored any address in letter, to do so you can use letter = &ch; where ch is some char variable.
That was all the lecture!!
Now my suggestion for your program:
You don't need to use letter pointer for the loop, a simple char i variable will be fine.
To re-form the string as you plan to, you can simply use the characters of the original string as indices to form new string. Declare a empty string of some large length, then keep concatenating the syllable[orig_string[i] - 'A'], inside a for loop till the end of orig_string. Assumption is orig_string contains all uppercase alphabets
Finally, Correct your printf syntax.
Do read about pointers in C from a good source, as they will never leave you, and will give you all sorts of nightmare.
Code
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *syllable[26] = {"a","bub","cash","dud","e","fud","gug","hash","i","jay",
"kuck","lul","mum","nun","o","pub","quack","rug","sus",
"tut","u","vuv","wack","xux","yuck","zug"};
void Tutnese(char *word, char *newword, size_t new_size);
void Tutnese(char *word, char *newword, size_t new_size)
{
char *end = newword + new_size;
char c;
while ((c = *word++) != '\0')
{
if (!isalpha(c))
*newword++ = c;
else
{
char *tut = syllable[tolower(c) - 'a'];
ptrdiff_t len = strlen(tut);
if (end - newword <= len)
break;
memcpy(newword, tut, len + 1);
newword += len;
}
}
*newword = '\0';
}
int main(void)
{
char i_data[1024];
char o_data[4096];
while (fgets(i_data, sizeof(i_data), stdin) != 0)
{
Tutnese(i_data, o_data, sizeof(o_data));
printf("I: %sO: %s", i_data, o_data);
}
return(0);
}
Output
I: computer
O: cashomumpubututerug
I: how do you tell mum that she cannot understand us?
O: hashowack dudo yuckou tutelullul mumumum tuthashatut sushashe cashanunnunotut ununduderugsustutanundud usus?
I: The quick brown fox jumped over the lazy dog.
O: tuthashe quackuicashkuck bubrugowacknun fudoxux jayumumpubedud ovuverug tuthashe lulazugyuck dudogug.
Lets forget about pointers and break down the problem.
You're given a word word and you want to create newword based on your mapping.
First, you need to figure out how big newword is.
To do that, iterate through the characters in word and add the string lengths of the mappings (call it N)
Once you've done that, you know you can allocate N+1 bytes (strings are null terminated in C) for newword (via malloc).
Then, you iterate through the characters again and just append to newword
Let me give you a few hints:
To iterate through a string (lets call it word), the C code would look like:
unsigned int wordlen = strlen(word);
for(unsigned int index = 0; index < wordlen; index++)
printf("Character at %u is %c", index, word[index]);
Your for loop is quite messed up. Do look up a few tutorials on pointers and string manipulation in C.

Why am i getting two different strings?

I wrote a very simple encryption program to practice c++ and i came across this weird behavior. When i convert my char* array to a string by setting the string equal to the array, then i get a wrong string, however when i create an empty string and add append the chars in the array individually, it creates the correct string. Could someone please explain why this is happening, i just started programming in c++ last week and i cannot figure out why this is not working.
Btw i checked online and these are apparently both valid ways of converting a char array to a string.
void expandPassword(string* pass)
{
int pHash = hashCode(pass);
int pLen = pass->size();
char* expPass = new char[264];
for (int i = 0; i < 264; i++)
{
expPass[i] = (*pass)[i % pLen] * (char) rand();
}
string str;
for (int i = 0; i < 264; i++)
{
str += expPass[i];// This creates the string version correctly
}
string str2 = expPass;// This creates much shorter string
cout <<str<<"\n--------------\n"<<str2<<"\n---------------\n";
delete[] expPass;
}
EDIT: I removed all of the zeros from the array and it did not change anything
When copying from char* to std::string, the assignment operator stops when it reaches the first NULL character. This points to a problem with your "encryption" which is causing embedded NULL characters.
This is one of the main reasons why encoding is used with encrypted data. After encryption, the resulting data should be encoded using Hex/base16 or base64 algorithms.
a c-string as what you are constructing is a series of characters ending with a \0 (zero) ascii value.
in the case of
expPass[i] = (*pass)[i % pLen] * (char) rand();
you may be inserting \0 into the array if the expression evaluates to 0, as well as you do not append a \0 at the end of the string either to assure it being a valid c-string.
when you do
string str2 = expPass;
it can very well be that the string gets shorter since it gets truncated when it finds a \0 somewhere in the string.
This is because str2 = expPass interprets expPass as a C-style string, meaning that a zero-valued ("null") byte '\0' indicates the end of the string. So, for example, this:
char p[2];
p[0] = 'a';
p[1] = '\0';
std::string s = p;
will cause s to have length 1, since p has only one nonzero byte before its terminating '\0'. But this:
char p[2];
p[0] = 'a';
p[1] = '\0';
std::string s;
s += p[0];
s += p[1];
will cause s to have length 2, because it explicitly adds both bytes to s. (A std::string, unlike a C-style string, can contain actual null bytes — though it's not always a good idea to take advantage of that.)
I guess the following line cuts your string:
expPass[i] = (*pass)[i % pLen] * (char) rand();
If rand() returns 0 you get a string terminator at position i.

How to read in only a particular number of characters

I have a small query regarding reading a set of characters from a structure. For example: A particular variable contains a value "3242C976*32" (char - type). How can I get only the first 8 bits of this variable. Kindly help.
Thanks.
Edit:
I'm trying to read in a signal:
For Ex: $ASWEER,2,X:3242C976*32
into this structure:
struct pg
{
char command[7]; // saves as $ASWEER,2,X:3242C976*32
char comma1[1]; // saves as ,2,X:3242C976*32
char groupID[1]; // saves as 2,X:3242C976*32
char comma2[1]; // etc
char handle[2]; // this is the problem, need it to save specifically each part, buts its not
char canID[8];
char checksum[3];
}m_pg;
...
When memcopying buffer into a structure, it works but because there is no carriage returns it saves the rest of the signal in each char variable. So, there is always garbage at the end.
you could..
convert your hex value in canID to float(depending on how you want to display it), e.g.
float value1 = HexToFloat(m_pg.canID); // find a conversion script for HexToFloat
CString val;
val.Format("0.3f",value1);
the garbage values aren't actually being stored in the structure, it only displays it as so, as there is no carriage return, so format the message however you want to and display it using the CString val;
If "3242C976*3F" is a c-string or std::string, you can just do:
char* str = "3242C976*3F";
char first_byte = str[0];
Or with an arbitrary memory block you can do:
SomeStruct memoryBlock;
char firstByte;
memcpy(&firstByte, &memoryBlock, 1);
Both copy the first 8bits or 1 byte from the string or arbitrary memory block just as well.
After the edit (original answer below)
Just copy by parts. In C, something like this should work (could also work in C++ but may not be idiomatic)
strncpy(m_pg.command, value, 7); // m.pg_command[7] = 0; // oops
strncpy(m_pg.comma, value+7, 1); // m.pg_comma[1] = 0; // oops
strncpy(m_pg.groupID, value+8, 1); // m.pg_groupID[1] = 0; // oops
strncpy(m_pg.comma2, value+9, 1); // m.pg_comma2[1] = 0; // oops
// etc
Also, you don't have space for the string terminator in the members of the structure (therefore the oopses above). They are NOT strings. Do not printf them!
Don't read more than 8 characters. In C, something like
char value[9]; /* 8 characters and a 0 terminator */
int ch;
scanf("%8s", value);
/* optionally ignore further input */
while (((ch = getchar()) != '\n') && (ch != EOF)) /* void */;
/* input terminated with ch (either '\n' or EOF) */
I believe the above code also "works" in C++, but it may not be idiomatic in that language
If you have a char pointer, you can just set str[8] = '\0'; Be careful though, because if the buffer is less than 8 (EDIT: 9) bytes, this could cause problems.
(I'm just assuming that the name of the variable that already is holding the string is called str. Substitute the name of your variable.)
It looks to me like you want to split at the comma, and save up to there. This can be done with strtok(), to split the string into tokens based on the comma, or strchr() to find the comma, and strcpy() to copy the string up to the comma.