I'm using the following functions :
hourFormat12() returns -> 1-12
minute() returns -> 1-60
How do I convert these integers into chars without knowing if the int is one or two digits?
I'm used to Java and Strings and I could typically do this when initializing a String :
String myString = "12" + ":" + "30" + "AM";
How can this be accomplished with a char array, without knowing the size of each of the strings.
Typical C way is to determine the maximum size that your output can be and use that as the size of your char array. There are macros in <limits.h> if you want to be 100% portable. Don't forget the null terminator!
You create a char array large enough to accomodate the data after inspecting it.
In this case, since the maximum required size of the array would be 8 chars (including null terminator) you can simply not bother with this and use a fixed size of 8.
Related
I'm working with char arrays in C. I'm setting the size in a previous step. When I print it out it clearly shows the num_digits as 1.
But then when I put it in to set the size of a char array to make it a char array of size num_digits, its setting the size of the array as 6.
In the next step when I print strlen(number_array), it prints 6. Printing it out I get something with a lot of question marks. Does anyone know why this is happening?
int num_digits = get_num_digits(number);
printf("Num digits are %d\n", num_digits);
char number_array[num_digits];
printf("String len of array: %d\n", strlen(number_array));
You need to null terminate your array.
char number_array[num_digits + 1];
number_array[num_digits] = '\0';
Without this null terminator, C has no way of know when you've reached the end of the array.
just use 'sizeof' instead of 'strlen'
printf("String len of array: %d\n", sizeof(number_array));
There are a couple possible issues I see here:
As noted in Michael Bianconi's answer, C character arrays (often called strings) require null terminators. You would explicitly set this this with something like:
number_array[number + 1] = '\0'; /* See below for why number + 1 */
Rather than just setting the last element to null, pre-initializing the entire character array to nulls might be helpful. Some compilers may do this for you, but if not you'll need to do this explicitly with something like:
for (int i = 0; i < num_digits + 1; i ++) number_array[i] = '\0';
Note that with gcc I had to use C99 mode using -std=c99 to get this to compile, as the compiler didn't like the initialization within the for statement.
Also, the code presented sets the length of the character array to be the same length as number's length. We don't know what get_num_digits returns, but if it returns the actual number of significant digits in an integer, this will come up one short (see above and other answer), as you need an extra character for the null terminator. An example: if the number is 123456 and get_number_digits returns 6, you would would need to set the length of number_array to 7, instead of 6 (i.e. number + 1).
char number_array[num_digits]; allocates some space for a string. It's an array of num_digits characters. Strings in C are represented as an array of characters, with a null byte at the end. (A null byte has the value zero, not to be confused with the digit character '0'.) So this array has room for a string of up to num_digits - 1 characters.
sizeof(number_array) gives you the array storage size. That's the total amount of space you have for a string plus its null terminator. At any given time, the array can contain a string of any length up to number_array - 1, or it might not contain a string at all if the array doesn't contain a null terminator.
strlen(number_array) gives you the length of the string contained in the array. If the array doesn't contain a null terminator, this call may return a garbage value or crash your program (or make demons fly out of your nose, but most computers fortunately lack the requisite hardware).
Since you haven't initialized number_array, it contains whatever happened to be there in memory before. Depending on how your system works, this may or may not vary from one execution of the program to the next, and this certainly does vary depending on what the program has been doing and on the compiler and operating system.
What you need to do is:
Give the array enough room for the null terminator.
Initialize the array to an empty string by making setting the first character to zero.
Optionally, initialize the whole array to zero. This is not necessary, but it may simplify further work with the array.
Use %zu rather than %d to print a size. %d is for an int, but sizeof and strlen return a size_t, which depending on your system may or may not be the same size of integers.
char number_array[num_digits + 1];
number_array[0] = 0; // or memset(number_array, 0, sizeof(number_array));
printf("Storage size of array: %zu\n", sizeof(number_array));
printf("The array contains an empty string: length=%zu\n", strlen(number_array));
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size=10;
char string1[50];
char *string2;
string2=(char *)malloc(size*sizeof(char));
fgets(string1,10,stdin);
printf("%s",string1);
fgets(string2,10,stdin);
printf("%s",string2);
}
There are two strings in this code one is an array and another one is dynamically created using pointer.
If my input is less than 50 for string1 and less than 10 for string2 will the space that is not filled get wasted ,if so how to reduce the size.
In case of string 2 malloc size parameter is 10 and fgets size parameters is 10 what will happen if i increase the size to fgets(string2,50,stdin) which is greater than malloc's size?
how to calculate the final size of input string in each case?I have used sizeof operator but it gave the hardcoded size that is 50 and 10 respectively for string1 and string2
Is there any other better approach to create a dynamic string?
Yes, it will be wasted. You can use variable-length arrays to use a different limit, or use dynamic allocation. Whether or not you should worry about the wasted space is a separate question: if your program reads strings that the user inputs manually (as opposed to reading a file) you can waste a lot of space before it starts to matter, unless you are on an embedded system with severe memory constraints.
You will get undefined behavior, so your program will be invalid. Don't do that - it is precisely why fgets takes the maximum length of the string.
Call strlen to compute the length of the string. Add 1 for null terminator. Remember that '\n' is part of the string when you use fgets and the input has '\n' in it.
You can use POSIX extension to scanf, and pass %ms format and a pointer to char*. This will allocate the string at the exact length, but your program will be less portable. Obviously, you are required to deallocate these strings to avoid memory leaks.
Say I want to create a String that will hold some values based on another string. Basically, I want to be able to compress one string, like this: aaabb -> a3b2 - But my question is:
In Java you could do something like this:
String mystr = "";
String original = "aaabb";
char last = original.charAt(0);
for (int i = 1; i < original.length(); i++) {
// Some code not relevant
mystr += last + "" + count; // Here is my doubt.
}
As you can see, we have initialized an empty string and we can modify it (mystr += last + "" + count;). How can you do that in C?
Unfortunately, in C you cannot have it as easy as in Java: string memory needs dynamic allocation.
There are three common choices here:
Allocate as much as you could possibly need, then trim to size once you are done - This is very common, but it is also risky due to a possibility of buffer overrun when you miscalculate the max
Run your algorithm twice - the first time counting the length, and the second time filling in the data - This may be the most efficient one if the timing is dominated by memory allocation: this approach requires you to allocate only once, and you allocate the precise amount of memory.
Allocate as you go - start with a short string, then use realloc when you need more memory.
I would recommend using the second approach. In your case, you would run through the source string once to compute the compressed length (in your case, that's 5 - four characters for the payload "a3b2", and one for the null terminator. With this information in hand, you allocate five bytes, then use the allocated buffer for the output, which is guaranteed to fit.
In C (not C++) you can do something like this:
char mystr[1024];
char * str = "abcdef";
char c = str[1]; // will get 'b'
int int_num = 100;
sprintf(mystr, "%s%c%d", str, c, int_num);
This will create a string in 'mystr':
"abcdefb100"
You can then concatenate more data to this string using strcat()
strcat(mystr, "xyz"); // now it is "abcdefb100xyz"
Please note that mystr has been declared to be 1024 bytes long and this is all the space you can use in it. If you know how long your string will be you can use malloc() in C to allocate the space and then use it.
C++ has much more robust ways of dealing with strings, if you want to use it.
You can use string concatenation method strcat:
http://www.cplusplus.com/reference/cstring/strcat/
You define your string as following:
char mystr[1024]; // Assuming the maximum string you will need is 1024 including the terminating zero
To convert the character last into a string to be able to concatenate it, you use the following syntax:
char lastString[2];
lastString[0] = last; // Set the current character from the for loop
lastString[1] = '\0'; // Set the null terminator
To convert the count into a string you need to use itoa function as following:
char countString[32];
itoa (count, countString, 10); // Convert count to decimal ascii string
Then you can use strcat as following:
strcat(mystr, lastString);
strcat(mystr, countString);
Another solution is to use STL String class or MFC CString if you are using Visual C++.
I want to find the length of this :
char *s[]={"s","a","b"};
it should count 4 with the /0 but the strlen or sizeof(s)/sizeof(char) gives me wrong answers..
How can i find it?
You are making an array of char* and not of char. That's why strlen won't work. Use
sizeof(s) / sizeof(char*) //should give 3
If you want a single string use
char s[] = "sab";
sizeof(s) / sizeof(s[0]) works no matter what type s contains.
What you have defined is not a string hence there is no NULL terminating character. Here you have declared pointers to 3 separate strings. BTW, you should declare your array as const char*.
There is no direct way to determine the length of an array in C. Arrays in C are represented by a continuous block in a memory.
You must keep the length of the array as a separate value.
strlen works if you terminate your array with null character. You cannot find number of elements in a char array unless you keep track of it. i.e store it in some variable like n. Every time you add member increment n and every time you remove decrement n
Why should it count 4? you have 3 pointers to char in this array, it should count 12 on most 32-bit platforms.
I'm using a char[] of size 4 but when I use memcpy() function it stores 8 characters in it and also the character array length becomes 8. What is happing?
I don't want to use malloc ok.
char strRoh[4]={'\0'};
and then
memcpy(strRoh,Dump+22,4);
Now tell me whats wrong with this
char strIP[]="hhhhhhhh";
char strRoh[4]={'\0'};
char strTheta[4]={'\0'};
char strTimeStamp[6]={'\0'};
char strNMDump[48]={'\0'};
is there any problem with decelerations cause when i change there order they strings also change there size now strroh is getting 10 chars
what a hell is going on with this
C strings are 0-terminated. This means that if you want to have a string of length n in C, you need n+1 chars for it:
char hello[5] = "hello";
is not a string, because hello has space for 5 chars, and it doesn't end with 0.
char hello[6] = "hello";
is a string, and has 6 characters: h, e, l, l, o, 0.
To be able to use string related functions in C, you need the terminating 0.
So, change your code to have:
char strRoh[5]={'\0'};
char strTheta[5]={'\0'};
char strTimeStamp[7]={'\0'};
char strNMDump[49]={'\0'};
Note that in C, when you do:
char hello[] = "hello";
the compiler does the counting for you, and makes hello an array of size 6 (one terminating 0):
printf("%zu\n", sizeof hello);
will print 6.
The underlying type of the objects pointed by both the source and destination pointers are irrelevant for memcpy; The result is a binary copy of the data.
The function does not check for any terminating null character in source - it always copies exactly num bytes. My guess is you are not adding a terminating null and trying to access it as a string.
C does not have any kind of boundary check on its data types.
So what you are probably "seeing" when debugging the code is that it shows you 8 bytes in the array. As someone else says, you might be trying to view it as a string and do not have a terminating zero byte. This is quite normal in C, and it is one of the aspects of the language that makes it very hard to understand.
I can recommend you read a good introduction to memory and pointer handling under C, or switch to a managed language like C#, VB.NET, Java, Perl, Python etc.
I suppose that if char has 2 bytes if you memcpy to a byte array you might be getting 8 bytes, that is 2 bytes for each char.
I am however rusty at this C/C++ things. So hopefully somebody with more experience will give you a better answer.
The problem is you have a char array of 4 bytes and you writing full 4 bytes during memcpy without leaving any space for the terminating null character. Declare your array as 5 bytes and initialize it all to null (which you are already doing) and everything should be fine.