Comparing chars one by one in a character array with strcmp [duplicate] - c++

This question already has answers here:
Comparing chars in a character array with strcmp
(3 answers)
Is there a possible way to use char in strcmp?
(2 answers)
Closed 1 year ago.
I'm writing a c++ script that compare chars of two strings one by one using strcmp().
I wrote this code:
char test1[1];
char test2[1];
test1[0]=str1[i]; //str1 is a char array
test2[0]=str2[i]; //str2 is a char array
int result=strcmp(test1,test2);
but if I print test1 or test2 I encountered with two chars.
for example if first index of str1='a' then test1 is "aa" but I don't know why?
Please Help.

strcmp() takes null-terminated strings, but neither of your char[] arrays are null-terminated.
char test1[2]; // <-- increase this!
char test2[2]; // <-- increase this!
test1[0] = str1[i];
test1[1] = '\0'; // <-- add this!
test2[0] = str2[i];
test2[1] = '\0'; // <-- add this!
int result = strcmp(test1, test2);
Otherwise, you can use strncmp() instead, which does not require null terminators, so no char[] arrays are needed, eg:
char test1 = str1[i];
char test2 = str2[i];
int result = strncmp(&test1, &test2, 1);
Or simply:
int result = strncmp(&str1[i], &str2[i], 1);
// or:
// int result = strncmp(str1+i, str2+i, 1);

Related

Insertion of character in an initialized array [closed]

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.

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().

Build code: "strlwr" by pointer [duplicate]

This question already has answers here:
Why can't I write to a string literal while I *can* write to a string object?
(4 answers)
Closed 8 years ago.
Someone can tell me different between this code:
char *s1 ="Con Chim Non";
and this one:
char *s=new char[100];
gets(s);
Then, I add the word: "Con Chim Non".
After, I build a code that change value of the pointer. In first code, I got a problem about the address. The second is right. And this is my code:
void Strlwr(char *s)
{
if (s == NULL )
return ;
for (int i = 0; s[i] != '\0'; ++i)
{
if ( s[i] <= 'Z' && s[i] >= 'A')
s[i] = s[i]+32;
}
}
And someone can tell me why the first is wrong.
The first example:
char *s1 ="Con Chim Non";
You declare a pointer to a text literal, which is constant. Text literals cannot be modified.
The proper syntax is:
char const * s1 = "Con Chim Non";
Note the const.
In your second example, you are declaring, reserving memory for 100 characters in dynamic memory:
char *s=new char[100];
gets(s);
You are then getting an unknown amount of characters from the input and placing them into the array.
Since you are programming in the C++ language, you should refrain from this kind of text handling and use the safer std::string data type.
For example, the gets function will read an unknown amount of characters from the console into an array. If you declare an array of 4 characters and type in 10, you will have a buffer overflow, which is very bad.
The std::string class will expand as necessary to contain the content. It will also manage memory reallocation.

How to concatenate a char * and a const char*? [duplicate]

This question already has answers here:
How do I concatenate const/literal strings in C?
(17 answers)
Closed 9 years ago.
I need to put "Hello World" in str3. How can I do this ?
const char *one = "Hello ";
char *two = "World";
char *str3;
You have to allocate void* malloc (size_t size); for str3 first then you can use sprintf to write in a string.
char *str3 = malloc(strlen(one) + strlen(two) + 1);
sprintf(str3, "%s%s", one, two); // ^ \0 termination
Adding #Nik Bougalis Suggestion:
One should know dynamic memory allocation in C. In my code I allocated using malloc() so latter in code when I don't need str3 we should explicitly deallocate memory using free() in C.
Also to avoid buffer-overflow always use snprintf instead of sprintf: So re-writing code as follows:
int length = strlen(one) + strlen(two) + 1;
char *str3 = malloc(length * sizeof(char));
snprintf(str3, length, "%s%s", one, two);
// write more code that uses str3
free(str3);
// now don't uses `str3`'s allocated memory
Read a book about C.
str3 = malloc(strlen(one) + strlen(two) + 1) ; // +1 for the 0 terminator
strcpy(str3, one) ;
strcat(str3, two) ;
...
free(str3) ; // frees allocated space when you are finished.
std::vector<char> v;
v.insert(v.end(), one, one + strlen(one));
v.insert(v.end(), two, two + strlen(two));
v.push_back('\0');
str3 = v.data();
String literals like "Hello" are stored in read-only memory, so you need to copy them somewhere where they can be modified.
So you must first allocate memory where the strings are to be stored. A simply char array will do. Then use strcpy() and strcat() to copy the string literals into that array.

Creating an array out of a string

I'm new to C++ and I've encountered a problem... I can't seem to create an array of characters from a string using a for loop. For example, in JavaScript you would write something like this:
var arr = [];
function setString(s) {
for(var i = s.length - 1; i >= 0; i--) {
arr.push(s[i]);
}
return arr.join("");
}
setString("Hello World!"); //Returns !dlroW olleH
I know it's a bit complicated, I do have a little bit of background knowledge on how to do it but the syntax of it is still not too familiar to me.
Is there any way that I could do that in c++ using arrays?
Could I join the array elements into one string as I do in JavaScript?
It would be greately appreciated if you could help. Thanks in advance.
If anyone needs more information just tell me and I'll edit the post.
By the way, my code in c++ is really messy at the moment but I have an idea of what I'm doing... What I've tried is this:
function setString(s) {
string arr[s.size() - 1];
for(int i = s.size() - 1; i >= 0; i--) {
arr[i] = s.at(i); //This is where I get stuck at...
//I don't know if I'm doing something wrong or not.
}
}
It would be nice if someone told me what I'm doing wrong or what I need to put or take out of the code. It's a console application compiled in Code::Blocks
std::string has the c_str() method that returns a C style string, which is just an array of characters.
Example:
std::string myString = "Hello, World!";
const char *characters = myString.c_str();
The closest thing to a direct translation of your function:
string setString(string s) {
string arr;
for(int i = s.length() - 1; i >= 0; i--) {
arr.push_back(s[i]);
}
return arr;
}
A std::string is a dynamic array underneath a fairly thin wrapper. There is no need to copy character by character, as it will do it properly for you:
If the character array is null-terminated (that is, the last element is a '\0'):
const char* c = "Hello, world!"; // '\0' is implicit for string literals
std::string s = c; // this will copy the entire string - no need for your loop
If the character array is not null-terminated:
char c[4] = {'a', 'b', 'c', 'd'}; // creates a character array that will not work with cstdlib string functions (e.g. strlen)
std::string s(c, 4); // copies 4 characters from c into s - again, no need for your loop
If you cannot use std::string (e.g. if you are forced to use ANSI C):
const char* c = "Hello, World!";
// assume c2 is already properly allocated to strlen(c) + 1 and initialized to all zeros
strcpy(c2, c);
In your javascript example, you are reversing the string, which can be done easily enough:
std::string s = "Hello, world!";
std::string s1(s.rbegin(), s.rend());
Additionally, you can cut your iterations in half (for both C++ and Javascript) if you fix your loop (pseudo-code below):
string s = "Hello, world!"
for i = 0 to s.Length / 2
char t = s[i]
s[i] = s[s.Length - 1 - t]
s[s.Length - 1 - i] = t
Which will swap the ends of the string to reverse it. Instead of looping through N items, you loop through a maximum of N / 2 items.