I have a char array and I want to find out the number of contents in it.
For example, my array is:
char myArray[10];
And after input it's content is:
ABC
Now I want to store in a variable 'size', the size of the area related to content. So, in this case:
size = 3
How do I find that?
A naive way of doing this would be to look for the null-terminating character \0, this is already implemented for you in the C-function strlen, so there are two ways of doing this:
int StringLength( const char* str, int maxLength )
{
for( int i = 0; i < maxLength; ++i )
{
if( str[i] == '\0' )
return i;
}
return -1;
}
Or you could just call strlen as follows:
int iLength = strlen( myArray );
However, as you have tagged this c++, the best way to do this would be to not deal with C-style character arrays and instead use the extremely useful std::string class.
strlen(myArray) is what you want.
Try this:
int len = strlen(myArray).
strlen is a part of stdlib.h library. Don't forget to declare it in your program.
defining array as char myArray[10]; will not always initialize it's content to zeros, so depending on how you fill it with ABC you either can or cannot find the corect lenght. In worst case regular strlen() will always report numbers >10, or even result in read access vialation. I try initialize it like char myArray[10] = {}; first
Related
I was wondering if and how one would compare an array of char pointers to a string.
So say I have this array of char pointers:
char *input[20];
And each index of input contained a string, for example, input[0] contained hello. What would I use if I needed to do a comparison to find a keyword contained within the input array?
Not really clear what your problem is here. But something like:
for ( int i = 0; i < 20; i++ ) {
if ( strcmp( input[i], "keyword" ) == 0 ) {
// found - do something
}
}
But in C++ you would be better off using std::string and std::vector rather than messing around with C-style arrays and pointers.
I have a char array called names[50]
Basically, I use
strncpy(this->names, names, sizeof(names))
however this will only truncate characters at the end.
How do I truncate characters from the start?
For example, BillSteveLinusMikeGeorgeBillSteveLinusMikeGeorgeGeorge should be teveLinusMikeGeorgeBillSteveLinusMikeGeorgeGeorge
If I have understood correctly then using the string you showed as an example you have to write
strncpy( this->names, names + 5, sizeof(names) - 5 );
You can change the source address for strncpy:
strncpy(this->names, &(names[10]), num_of_chars_to_copy);
Notice that no null-character is implicitly appended at the end of the destination string if the source string is longer than num.
You need to be clear what you want to do... is names[] variable in length from call to call? Is this->names a fixed length? Note that the length for the number of bytes to copy should be the number of bytes available in this->names... Otherwise you run the risk of overflowing the memory.
I designed for you this simple function, You can use it as reference code for more complex issue:
void BackStrCopy(char* src, char* dest, int srcsize, int destsize)
{
if(srcsize >= destsize )
{
do
dest[destsize--] = src[srcsize--];
while( destsize + 1 );
}
}
int main()
{
char* src = "BillSteveLinusMikeGeorgeBillSteveLinusMikeGeorgeGeorge";
char dest[50];
BackStrCopy(src, dest, strlen(src), 25);
}
I tested it end work.
I thing that the function code does not require any comment:)
If my solution help you, please remember to check it as answered.
Ciao
I want to use mbstowcs_s method but without iostream header. Therefore I cannot use strlen to predict the size of my buffer. The following method has to simply change c-string to wide c-string and return it:
char* changeToWide(char* value)
{
wchar_t* vOut = new wchar_t[strlen(value)+1];
mbstowcs_s(NULL,vOut,strlen(val)+1,val,strlen(val));
return vOut;
}
As soon as i change it to
char* changeToWide(char* value)
{
wchar_t* vOut = new wchar_t[sizeof(value)];
mbstowcs_s(NULL,vOut,sizeof(value),val,sizeof(value)-1);
return vOut;
}
I get wrong results (values are not the same in both arrays). What is the best way to work it out?
I am also open for other ideas how to make that conversion without using strings but pure arrays
Given a char* or const char* you cannot use sizeof() to get the size of the string being pointed by your char* variable. In this case, sizeof() will return you the number of bytes a pointer uses in memory (commonly 4 bytes in 32-bit architectures and 8 bytes in 64-bit architectures).
If you have an array of characters defined as array, you can use sizeof:
char text[] = "test";
auto size = sizeof(text); //will return you 5 because it includes the '\0' character.
But if you have something like this:
char text[] = "test";
const char* ptext = text;
auto size2 = sizeof(ptext); //will return you probably 4 or 8 depending on the architecture you are working on.
Not that I am an expert on this matter, but char to wchar_t conversion being made is seemingly nothing but using a wider space for the exact same bytes, in other words, prefixing each char with some set of zeroes.
I don't know C++ either, just C, but I can derive what it probably would look like in C++ by looking at your code, so here it goes:
wchar_t * changeToWide( char* value )
{
//counts the length of the value-array including the 0
int i = 0;
while ( value[i] != '\0' ) i++;
//allocates enough much memory
wchar_t * vOut = new wchar_t[i];
//assigns values including the 0
i = 0;
while ( ( vOut[i] = 0 | value[i] ) != '\0' ) i++;
return vOut;
}
0 | part looks truly obsolete to me, but I felt like including it, don't really know why...
I'm making a lexical analyzer and this is a function out of the whole thing. This function takes as argument a char, c, and appends this char to the end of an already defined char* array (yytext). It then increments the length of the text (yylen).
I keep getting segfaults on the shown line when it enters this function. What am I doing wrong here? Thanks.
BTW: can't use the strncpy/strcat, etc. (although if you want you can show me that implementation too)
This is my code:
extern char *yytext;
extern int *yylen;
void consume(char c){
int s = *yylen + 1; //gets yylen (length of yytext) and adds 1
//now seg faults here
char* newArray = new char[s];
for (int i = 0;i < s - 1;i++){
newArray[i] = yytext[i]; //copy all chars from existing yytext into newArray
}
newArray[s-1] = c; //append c to the end of newArray
for (int i = 0;i < s;i++){ //copy all chars + c back to yytext
yytext[i] = newArray[i];
}
yylen++;
}
You have
extern int *yylen;
but try to use it like so:
int s = (int)yylen + 1;
If the variable is an int *, use it like an int * and dereference to get the int. If it is supposed to be an int, then declare it as such.
That can t work:
int s = (int)yylen + 1; //gets yylen (length of yytext) and adds 1
char newArray[s];
use malloc or a big enought buffer
char * newarray=(char*)(malloc(s));
Every C-style string should be null-terminated. From your description it seems you need to append the character at c. So, you need 2 extra locations ( one is for appending the character and other for null-terminator ).
Next, yylen is of type int *. You need to dereference it to get the length (assuming it is pointing to valid memory location ). So, try -
int s = *yylen + 2;
I don't see the need of temporary array but there might be a reason why you are doing it. Now,
yytext[i] = newArray[i]; //seg faults here
you have to check if yytext is pointing to a valid write memory location. If yes, then is it long enough to fill the appending character plus null terminator.
But I would recommend using std::string than working with character arrays. Using it would be a one liner to solve the problem.
I need an empty char array, but when i try do thing like this:
char *c;
c = new char [m];
int i;
for (i = 0; i < m; i++)
c[i] = 65 + i;
and then I print c. can see that c = 0x00384900 "НННННННээээ««««««««юоюою"
after cycle it becomes: 0x00384900 "ABCDEFGээээ««««««««юоюою"
How can I solve this problem? Or maybe there is way with string?
If you're trying to create a string, you need to make sure that the character sequence is terminated with the null character \0.
In other words:
char *c;
c = new char [m+1];
int i;
for (i = 0; i < m; i++)
c[i] = 65 + i;
c[m] = '\0';
Without it, functions on strings like printf won't know where the string ends.
printf("%s\n",c); // should work now
If you create a heap array, OS will not initialiase it.
To do so you hvae these options:
Allocate an array statically or globally. The array will be filled with zeroes automatically.
Use ::memset( c, 0, m ); on heap-initialised or stack array to fill it with zeroes.
Use high-level types like std::string.
I believe that's your debugger trying to interpret the string. When using a char array to represent a string in C or C++, you need to include a null byte at the end of the string. So, if you allocate m + 1 characters for c, and then set c[m] = '\0', your debugger should give you the value you are expecting.
If you want a dynamically-allocated string, then the best option is to use the string class from the standard library:
#include <string>
std::string s;
for (i = 0; i < m; i++)
s.push_back(65 + i);
C strings are null terminated. That means that the last character must be a null character ('\0' or just 0).
The functions that manipulate your string use the characters between the beginning of the array (that you passed as parameter, first position in the array) and a null value. If there is no null character in your array the function will iterate pass it's memory until it finds one (memory leak). That's why you got some garbage printed in your example.
When you see a literal constant in your code, like printf("Hello");, it is translate into an array of char of length 6 ('H', 'e', 'l', 'l', 'o' and '\0');
Of course, to avoid such complexity you can use std::string.