Apologies if my following question sounds trivial but I'm struggling with the fundamental concept of "converting an a char array to a string" for use in the method strstr().
Essentially I have an array called EUI_only[] which is dynamically populated at a certain stage of my program i.e.
EUI_only[0] = A;
EUI_only[1] = B;
EUI_only[2] = C;
EUI_only[3] = D;
EUI_only[4] = E;
I declared EUI_only as follows at the top of my program:
char EUI_only[];
I can confirm that EUI_only[] is successfully populated as justbefore I use it in method strstr() I print it out.
Now I have the second array called receive_key_press_temporary_analysis_buffer which I intend on utilising in my strstr() i.e. the array which contains characters similar to those in EUI_only.
This array is also dynamically populated in a certain point of my program and I can confirm that the contents of the array are intact just before I use it in strstr() as I've printed this array.
Content of this array called receive_key_press_temporary_analysis_buffer can be seen below:
receive_key_press_temporary_analysis_buffer[0] = 1;
receive_key_press_temporary_analysis_buffer[1] = 2;
receive_key_press_temporary_analysis_buffer[2] = C;
receive_key_press_temporary_analysis_buffer[3] = A;
receive_key_press_temporary_analysis_buffer[4] = B;
receive_key_press_temporary_analysis_buffer[5] = C;
receive_key_press_temporary_analysis_buffer[6] = D;
receive_key_press_temporary_analysis_buffer[7] = E;
receive_key_press_temporary_analysis_buffer[8] = 3;
receive_key_press_temporary_analysis_buffer[9] = 4;
Below essentially is how I use both arrays in strstr():
char* is_eui_only_content_in_receive_key_press_analysis = strstr(receive_key_press_temporary_analysis_buffer, EUI_only);
printf("\n\rResult of is_eui_only_content_in_receive_key_press_analysis: %s\n\r", is_eui_only_content_in_receive_key_press_analysis);
Basically when I print the outcome of strstr() it gives me:
Result of is_eui_only_content_in_receive_key_press_analysis: CDE34
On the other hand if I reinitialise my EUI_only follows:
EUI_only[] = "ABCDE";
Essentially I get the expected result from the strstr() i.e.
Result of is_eui_only_content_in_receive_key_press_analysis: ABCDE34
Why could it be the strstr() doesn't give me my expected result when I utilise my dynamically populated EUI_only[] array?
Thanks,
Alex.
If your only definition is char EUI_only[]; then it actually has a size of 1. You cause a buffer overflow by writing 5 characters to it. In C, arrays don't automatically resize; they have a fixed size for their lifetime.
Successfully printing its contents doesn't prove anything, as it could perhaps happen that you write into memory you don't own, but nothing disturbs that memory in between the write and the read.
Secondly, the str functions expect a string. The definition of a string is a series of characters followed by a null character. In your example code you do not have the null character, so even if you did not have the allocation problem, you don't actually have a string; therefore the function misbehaves.
When you write char EUI_only[] = "ABCDE"; , it is doing char EUI_only[6] = { 'A', 'B', 'C', 'D', 'E', 0 }; which is a string, so everything works as expected.
Update: The reason the array size would be 1 is covered by C99 6.9.2, "tentative definitions". After the line char EUI_only[];, EUI_only has incomplete type. For an incomplete array type, you can dereference it, but you can't do sizeof on it. You may complete the type at any point later on in the source file; and if you don't, then it behaves as if the last line of the source file was char EUI_only[] = { 0 };. This is a rarely-used feature of C; usually you would declare a complete type by either specifying the size, or providing an initializer.
C strings are terminated by null '\0' character
EUI_only[5] = '\0' ;
and
receive_key_press_temporary_analysis_buffer[10] = '\0' ;
Make sure you have extra space for null character at declaration.
Related
I've recently started to try learn the C programming language. In my first program (simple hello world thing) I came across the different ways to declare a string after I realised I couldn't just do variable_name = "string data":
char *variable_name = "data"
char variable_name[] = "data"
char variable_name[5] = "data"
What I don't understand is the difference between them. I know they are different and one of them specifically allocates an amount of memory to store the data in but that's about it, and I feel like I need to understand this inside out before moving onto more complex concepts in C.
Also, why does using *variable_name let me reassign the variable name to a new string but variable_name[number] or variable_name[] does not? Surely if I assign, say, 10 bytes to it (char variable_name[10] = "data") and try reassigning it to something that is 10 bytes or smaller it should work, so why doesn't it?
What are the empty brackets and the asterix doing?
In this declaration
char *variable_name = "data";
there is declared a pointer. This pointer points to the first character of the string literal "data". The compiler places the string literal in some region of memory and assigns the pointer by the address of the first character of the literal.
You may reassign the pointer. For example
char *variable_name = "data";
char c = 'A';
variable_name = &c;
However you may not change the string literal itself. An attempt to change a string literal results in undefined behaviour of the program.
In these declarations
char variable_name[] = "data";
char variable_name[5] = "data";
there are declared two arrays elements of which are initialized by characters of used for the initialization string literals. For example this declaration
char variable_name[] = "data";
is equivalent to the following
char variable_name[] = { 'd', 'a', 't', 'a', '\0' };
The array will have 5 elements. So this declaration is fully euivalent to the declaration
char variable_name[5] = "data";
There is a difference if you would specify some other size of the array. For example
char variable_name[7] = "data";
In this case the array would be initialized the following way
char variable_name[7] = { 'd', 'a', 't', 'a', '\0', '\0', '\0' };
That is all elements of the array that do not have explicit initializers are zero-initialized.
Pay attention to that in C you may declare a character array using a string literal the following way
char variable_name[4] = "data";
that is the terminating zero of the string literal is not placed in the array.
In C++ such a declaration is invalid.
Of course you may change elements of the array (if it is not defined as a constant array) if you want.
Take into account that you may enclose a string literal used as an initializer in braces. For example
char variable_name[5] = { "data" };
In C99 you may also use so-called destination initializers. For example
char variable_name[] = { [4] = 'A', [5] = '\0' };
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
int main(void)
{
char variable_name[] = { [4] = 'A', [5] = '\0' };
printf( "%zu\n", sizeof( variable_name ) );
printf( "%zu\n", strlen( variable_name ) );
return 0;
}
The program output is
6
0
When ypu apply standard C function strlen declared in header <string.h> you get that it returns 0 because the first elements of the array that precede the element with index 4 are zero initialized.
i just started to learn how to program and i encountered this error that goes like this: "initialization makes integer from pointer without a cast [enabled by default]"
What is the problem?
// This program pairs three kids with their favorite superhero
#include <stdio.h>
#include <string.h>
main()
{
char Kid1[12];
// Kid1 can hold an 11-character name
// Kid2 will be 7 characters (Maddie plus null 0)
char Kid2[] = "Maddie";
// Kid3 is also 7 characters, but specifically defined
char Kid3[7] = "Andrew";
// Hero1 will be 7 characters (adding null 0!)
char Hero1 = "Batman";
// Hero2 will have extra room just in case
char Hero2[34] = "Spiderman";
char Hero3[25];
Kid1[0] = 'K'; //Kid1 is being defined character-by-character
Kid1[1] = 'a'; //Not efficient, but it does work
Kid1[2] = 't';
Kid1[3] = 'i';
Kid1[4] = 'e';
Kid1[5] = '\0'; // Never forget the null 0 so C knows when the
// string ends
strcpy(Hero3, "The Incredible Hulk");
printf("%s\'s favorite hero is %s.\n", Kid1, Hero1);
printf("%s\'s favorite hero is %s.\n", Kid2, Hero2);
printf("%s\'s favorite hero is %s.\n", Kid3, Hero3);
return 0;
}
The problem is with char Hero1 = "Batman":
When you use a double-quoted string of characters in your code, the compiler replaces it with a pointer to the beginning of the memory space in which the string will reside during runtime.
So by char Hero1 = "Batman", you are actually attempting to assign a memory address (which typically consists of 32 or 64 bits of data, depending on your system) into a character variable (which typically stores 8 bits of data).
In order to fix the problem, you need to change it to either one of the following options:
char Hero1[] = "Batman"
char* Hero1 = "Batman"
FYI, in both cases above, the string "Batman" will reside in a read-only memory section during runtime.
However, there is a notable difference between these two cases:
Using char Hero1[], the "Batman" string will be copied into the stack every time the function is called. The Hero1 array will start at that address, and you will be able to change the contents of that array at a later point within the function.
Using char* Hero1, the "Batman" string will not be copied into the stack every time the function is called. The Hero1 variable will be pointing to the original address of the string, hence you will not will be able to change the contents of that string at any point within the function.
When the executable image is generated from your code, the string is placed in the code-section, which is one of several memory-sections within the program. The compiler then replaces the so-called "string assignment" with a so-called "integer assignment".
For example, char* x = "abc" is changed into char* x = (char*)0x82004000 before being compiled into object code, where 0x82004000 is the (constant) address of the string in the program's memory space.
When you do sizeof("abc"), the executable image will not even contain the "abc" string, since there is no "runtime" operation performed on this string.
There is no object code generated for sizeof - the compiler computes this value during compilation, and immediately replaces it with a constant.
You can look into the (intermediate) map file that is usually generated, and see that the input string of that sizeof operation does not appear anywhere.
char Hero1 = "Batman";
should be
char Hero1[] = "Batman";
A couple times you have some issues:
#include <stdio.h>
#include <string.h>
main()
{
char Kid1[12];
// Kid1 can hold an 11-character name
// Kid2 will be 7 characters (Maddie plus null 0)
char Kid2[] = "Maddie";
// Kid3 is also 7 characters, but specifically defined
char Kid3[7] = "Andrew";
// Hero1 will be 7 characters (adding null 0!)
char *Hero1 = "Batman"; //needs to be a pointer
// Hero2 will have extra room just in case
char *Hero2 = "Spiderman"; //needs to be a pointer
char Hero3[25]
Kid1[0] = 'K'; //Kid1 is being defined character-by-character
Kid1[1] = 'a'; //Not efficient, but it does work
Kid1[2] = 't';
Kid1[3] = 'i';
Kid1[4] = 'e';
Kid1[5] = '\0'; // Never forget the null 0 so C knows when the
// string ends
strcpy(Hero3, "The Incredible Hulk");
printf("%s\'s favorite hero is %s.\n", Kid1, Hero1);
printf("%s\'s favorite hero is %s.\n", Kid2, Hero2);
printf("%s\'s favorite hero is %s.\n", Kid3, Hero3);
return 0;
}
You should define all of your vars at the top of the function, its a good C practice.
Other than that, I flagged the issues (and corrected them) with comments.
Solution:
This error you get because String data type is not in C
programming you can print string by using array or char pointer like
1.Array:
#include<stdio.h>
int main(){
char a[]={'a','b','c','d','f','\0'};
printf("%s",a);
return 0;
}
Click here to check the output of solution array
2.char pointer:
#include<stdio.h>
int main(){
char* a="abcd";
printf("%s",a);
return 0;
}
Click here to check the output of solution char pointer
Newbie to programming (school) and I'm a little confused on what/why this is happening.
I have a loop that is iterating over an array of elements, for each element I am taking the integer of the array, converting it to a char using the function getelementsymbol, and using strcat to append to my temp array. The problem I am having is that the elements of my temp array contain the residual of the element proceeding it. This is the snippet of my code. The output I receive is this:
word1
word1word2
word1word2word3
char* elementsBuildWord(const int symbols[], int nbSymbols){
/* ROLE takes a list of elements' atomic numbers and allocate a new string made
of the symbols of each of these elements
PARAMETERS symbols an array of nbSymbols int which each represent the atomic number
of an element
nbSymbols symbols array's size
RETURN VALUE NULL if the array is of size <= 0
or if one of the symbols is not found by our getElementSymbol function
other the address of a newly allocated string representing the concatenation
of the names of all symbols
*/
char s1[MAX_GENERATED_WORD_LENGTH];
int y;
char *s2;
size_t i;
for (i = 0; i < nbSymbols; i++){
y = symbols[i];
s2 = getElementSymbol(y);
strcat(s1, s2);
}
printf("%s ", s1);
}
Firstly, your s1 is not initialized. strcat function append a new string to an existing string. This means that your s1 has to be a string from the very beginning. An uninitialized char array is not a string. A good idea would be to declare your s1 as
char s1[MAX_GENERATED_WORD_LENGTH] = { 0 };
or at least do
s1[0] = '\0';
before starting your cycle.
Secondly, your getElementSymbol function returns a char * pointer. Where does that pointer point to? Who manages the memory it points to? This is non-obvious from your code. It is possible that the function returns an invalid pointer (like a pointer to a local buffer), which is why might see various anomalies. There's no way to say without seeing how it is implemented.
strcat is supposed to append to a string. use strcpy if you want to overwrite the existing string. You could also use s1[0] = '\0'; before strcat to "blank" the string if you really want to, but looks like you really want strcpy.
From the snippet above it's not even clear why you need s1 - you could just print s2...
I wrote the function to concatenate two strings using pointers. Like strcat(s,t), so at the end of s, t will be added..
int main ()
{
char b[] = "Hello";
char b1[] = "world";
string_cat(b,b1);
printf("Concatenated string is %s\n",b);
return 0;
}
int string_cat(char *s, char *d)
{
while(*++s != '\0')
;
*s++ = ' ';
while((*s++ = *d++)!='\0'); // Concatenation
printf("S is %c\n",s[-2]); // Just to see the values
}
Concatenation works fine, but when I want to see the way elements are stored, all the elements are stored in negative direction, what I mean is s[-2] equals to 'd', s[-3] equals 'l' .. Is this the way they are stored?
First up b is too small to hold the concatenated string. It has only enough space to hold Hello\0 so what you are doing is undefined. Second, look at this line:
while((*s++ = *d++)!='\0');
^^^
You're advancing s because you're incrementing it. Each time you increment it you should imagine it points one element forward. When you get to the end, s isn't what it started out to be. So s[-2] is actually farther down the line compared to the original s (b in your case).
EDIT
so, how to declare it, so that it dynamically adjusts to new size?
Making it adjust to the right size it tough, if possible. What you can do:
Declare it like so: char b[LENGTH] = "Hello";
Pass another parameter to string_cat specifying the size
After multiple iterations you will eventually end up with something like strncpy / memcpy.
Its not stored in negative direction but rather, because you are incrementing the pointer (*s++ in the while loop while((*s++ = *d++)!='\0');)while concatenating , so at the end s points to the end of the string.
You may want to save a copy of the pointer to ensure that you don't loose the beginning of the string (if you need) inside string_cat
Your code has other potential problems which would lead to stack buffer overrun.
char b[] = "Hello";
is a fixed size buffer. Concatenating b1 with b would eventually lead to buffer overrun causing a UB and might eventually crash.
I'm not used to C as I'm primarily a Java guy, with some knowledge of C++, so forgive me if this is a trivial question. I could not seem to find an answer while searching online.
I'm initializing a char array...
char tcp[50];
So that I can concatenate a const char and a char. In examples I saw an easy way to do this was by creating that empty char array and then using...
strcat(x,y);
To stick them together.
Problem is, printing out the blank char array when it is set to "50" gives me a result of:
X??|?
When I change it to...
char tcp[100];
And print it, its blank. Why is this?
The array contents are undefined, assuming it is a local (automatic) array.
Use:
char tcp[50] = "";
Or:
char tcp[50] = {0};
Or:
char tcp[50];
tcp[0] = 0;
Or:
char tcp[50];
memset(tcp, 0, sizeof(tcp));
As you like.
Always null terminate you char arrays before doing anything:
tcp[0] = '\0';
C happily allocates the space for the array you declare, but it does not set its content to 0.
Therefore, the content of the array you're printing is random (or rather depending in the previous contents of the memory)
When creating an array, the compiler puts it somewhere in memory but does not initialize it, so whatever is in that memory when the program is started will be the initial "string".
Terminate the string manually after you created the array, either by making the whole array "zeroed" out, or just put zero as the first character:
char tcp[50] = { '\0' };
Or
char tcp[50];
/* ... */
tcp[0] = '\0';
The difference here is, you're essentially working with two empty arrays trying to merge them in the memory space of one (not sure if that makes sense for you).
First of all, in C you have to terminate strings with \0. That's something not exposed or visible in Java. Also you essentially used two undefined strings (as there's no value set).
#include <stdio.h>
#include <string.h>
char target[256];
const char source_a[] = "Hello";
const char source_b[] = "World!";
int void(main)
{
target[0] = '\0'; // this essentially empties the string as we set the first entry to be the end. Depending on your language version of C, you might as well write "char target[256] = {'\0'};" above.
strcat(target, source_a); // append the first string/char array
strcat(target, " "); // append a const string literal
strcat(target, source_b); // append the second string
printf("%s\n", target);
return 0;
}
Important: Using strcat() can be unsave, as there's no length check performed, and other than Java, these "strings" have a fixed length (the one you set when defining the variables). If there's no length given, but you copy a string on initialization, that length is taken (e.g. char test[] = "Hello!"; will be 7 chars long (due to terminating \0)).
If you'd like a more Java like approach on strings, use C++ and the std::string class, that performs a lot more similar to Java's strings.