STM32 C : atoi converts part of string which is not an argument - c

I have parsed some date and time from GPS receiver. And need to convert them from string to int:
char year[4] = "2014";
char month[2] = "01";
char day[2] = "24";
char hour[2] ="12";
char minute[2] = "58";
char second[2] = "39";
GPS_current_year = atoi(year);
GPS_current_month = atoi(month);
GPS_current_day = atoi(day);
GPS_current_hour = atoi(hour);
GPS_current_minute = atoi(minute);
GPS_current_second = atoi(second);
After executing these the results are:
Somehow part of minutes string is converted when converting hour string. Same with minutes and seconds.
The strings are placed side by side in the memory.
If I change the sequence of defining strings then seconds may be added to years etc.
Questions:
What may cause this error?
Is there any way to avoid this error with using atoi?
I know that I can convert using a loop one char at a time. Just trying to find why is it not working.

Besides the missing quotes around the strings your char array's size should be defined to hold one more char the EOS (end of string a binary zero).
Since the memory representation would be e.g. "2014\0"
char year[4+1] = "2014";

Suggest not trying to define the string size as 4 or 5.
Let the compiler determine the string size.
char year[] = "2014";
In this case, the compiler will make year with a size of 5 initialized with '2', '0', '1', '4', '\0'.
OP's defining the size as 4 resulted in a size of 4-char array without a terminating '\0', which not being a string, create problems with atoi(year).

You forgot quotes in the strings:
char year[4] = "2014";

atoi() converts string to integer. But you are giving non string values to your string variables. Change your code to
char year[5] = "2014";
char month[3] = "01";
char day[3] = "24";
char hour[3] ="12";
char minute[3] = "58";
char second[3] = "39";

Related

Convert char String to an int but not possible to convert a char from an char string to an int?

char input[5] = "12345";
printf("Convert to int valid %d", atoi(input));
printf("Convert to int invalid %d", atoi(input[1])); // program crash
Is there a solution to convert an char "slice" of an char string into an int?
Short description:
User inputs a string with values for example: 1, 2 3 4 ,5
Iam formating that string to 12345
With each number i want to continue to work with the index of an array.
If you mean "how to access a substring in the char [] array", you can use pointer arithmetic:
char input[6] = "12345";
printf("strtol(input + 1) = %d\n", strtol(input + 1, NULL, 10)); // Output = "2345";
Few things to note though:
Your array should be 6 elements long to hold the null terminator
atoi shouldn't be used at all; strtol is a better function for the task of converting a string to a signed integer; see here for more info.
Also, to convert a single character to an int:
if(isdigit(c))
{
c -= '0';
}
The relation that a textual representation of a digit is exactly '0' higher than the numeric value of that digit is guaranteed to hold for every character set supported by C.
To properly convert an arbitrary slice, you have to either make a copy or modify the string by inserting a \0 after the slice. The latter may not be an option, depending on where the string is stored.
To make a copy, allocate an array big enough to hold the slice and a \0. If you know the size of the slice at compile time, you can allocate on the stack:
char slice[2];
Otherwise, you'll have to allocate dynamically:
char *slice;
slice = malloc(2);
Stack allocated slices do not need to be deallocated, but dynamically allocated ones should be freed as soon as they are no longer needed:
free(slice);
Once you have the slice allocated, copy the portion of interest and terminate it with \0:
strncpy(slice, s + 1, 1);
slice[1] = '\0';
atoi(slice);
This technique will pretty much always work.
If your slice always ends with the string, you don't need to make a copy: you just need to pass a pointer to the start of the slice:
atoi(s + 1);
Modifying the string itself probably won't work, unless it's in writeable memory. If you're sure this is the case, you can do something like:
char tmp;
tmp = s[1];
s[1] = '\0';
atoi(s);
s[1] = tmp;
If you were sure but the memory wasn't writeable, your program will seg-fault.
For the special case where your slice is exactly one character long, you can use the fact that characters are numbers:
s[0] - '0'
Note that '0' !='\0' and that this won't work if your machine uses EBCDIC or similar.

In C turning a char into a string

I am reading from a file using fgetc and doing that makes it so that I have a char. However, I want to convert this char to a string such that I can use the strtok function upon it. How would I go about doing this?
int xp;
while(1) {
xp = fgetc(filename);
char xpchar = xp;
//convert xpchar into a string
}
Simply create an array with two items, your character and the null terminator:
char str[] = {ch, '\0'};
Or if you will, use a compound literal to do the same:
(char[]){ch, '\0'}
Compound literals can be used to convert your character directly, inside an expression:
printf("%s", (char[]){ch, '\0'} );
I suppose, you are going to read not just one character from file, so look at the following example:
#define STR_SIZE 10
// STR_SIZE defines the maximum number of characters to be read from file
int xp;
char str[STR_SIZE + 1] = { 0 }; // here all array of char is filled with 0
// +1 in array size ensure that at least one '\0' char
// will be in array to be the end of string
int strCnt = 0; // this is the conter of characters stored in the array
while (1) {
xp = fgetc(f);
char xpchar = xp;
//convert xpchar into a string
str[strCnt] = xpchar; // store character to next free position of array
strCnt++;
if (strCnt >= STR_SIZE) // if array if filled
break; // stop reading from file
}
And name of your file-pointer-variable - filename looks strange (filename is good name for string variable that store name of file, but fgetc and getc need FILE *), so check that in your program you have something like:
FILE * f = fopen(filename, "r");
or think over changing name for filename.

Sizeof(char[]) in C

Consider this code:
char name[]="123";
char name1[]="1234";
And this result
The size of name (char[]):4
The size of name1 (char[]):5
Why the size of char[] is always plus one?
Note the difference between sizeof and strlen. The first is an operator that gives the size of the whole data item. The second is a function that returns the length of the string, which will be less than its sizeof (unless you've managed to get string overflow), depending how much of its allocated space is actually used.
In your example
char name[]="123";
sizeof(name) is 4, because of the terminating '\0', and strlen(name) is 3.
But in this example:
char str[20] = "abc";
sizeof(str) is 20, and strlen(str) is 3.
As Michael pointed out in the comments the strings are terminated by a zero. So in memory the first string will look like this
"123\0"
where \0 is a single char and has the ASCII value 0. Then the above string has size 4.
If you had not this terminating character, how would one know, where the string (or char[] for that matter) ends? Well, indeed one other way is to store the length somewhere. Some languages do that. C doesn't.
In C, strings are stored as arrays of chars. With a recognised terminating character ('\0' or just 0) you can pass a pointer to the string, with no need for any further meta-data. When processing a string, you read chars from the memory pointed at by the pointer until you hit the terminating value.
As your array initialisation is using a string literal:
char name[]="123";
is equivalent to:
char name[]={'1','2','3',0};
If you want your array to be of size 3 (without the terminating character as you are not storing a string, you will want to use:
char name[]={'1','2','3'};
or
char name[3]="123";
(thanks alk)
which will do as you were expecting.
Because there is a null character that is attached to the end of string in C.
Like here in your case
name[0] = '1'
name[1] = '2'
name[2] = '3'
name[3] = '\0'
name1[0] = '1'
name1[1] = '2'
name1[2] = '3'
name1[3] = '4'
name1[4] = '\0'
A String in C (and in, probably, every programming language - behind the scenes) is an array of characters which is terminated by \0 with the ASCII value of 0.
When assigning: char arr[] = "1234";, you assign a string literal, which is, by default, null-terminated (\0 is also called null) as you can see here.
To avoid a null (assuming you want just an array of chars and not a string), you can declare it the following way char arr[] = {'1', '2', '3', '4'}; and the program will behave as you wish (sizeof(arr) would be 4).
name = {'1','2','3','\0'};
name1 = {'1','2','3','4','\0'};
So
sizeof(name) = 4;
sizeof(name1) = 5;
sizeof returns the size of the object and in this case the object is an array and it is defined that your array is 4 bytes long in first case and 5 bytes in second case.
In C, string literals have a null terminating character added to them.
Your strings,
char name[]="123";
char name1[]="1234";
look more like:
char name[]="123\0";
char name1[]="1234\0";
Hence, the size is always plus one. Keep in mind when reading strings from files or from whatever source, the variable where you store your string, should always have extra space for the null terminating character.
For example if you are expected to read string, whose maximum size is 100, your buffer variable, should have size of 101.
Every string is terminated with the char nullbyte '\0' which add 1 to your length.

How to combined the char value to int?

I have a char array like the following
charArray[0] = '1'
charArray[1] = '2'
charArray[2] = '3'
charArray[3] = '4'
charArray[4] = '5'
How to combined the char value of above array into a int like the following ?
But I don't want to combined all the value in to a int
I only want to combined charArray[0]~charArray[3] into int
int number = 1234;
How to combined the char value of above array into a string ?
I hope, by showing you the following line, this will give you a better idea how to tackle programming problems.
int number = (charArray[0] - '0')*1000 +
(charArray[1] - '0')*100 +
(charArray[2] - '0')*10 +
(charArray[3] - '0');
Cheers.
You should use the atoi function:
int atoi (const char * str);
recives a string and returns it as a value of type int.
and the function stncpy:
char * strncpy ( char * destination, const char * source, size_t num );
Copies the first num characters of source to destination.
Create a new string(with the strncpy function) containing only the 4 first chars of the charArray and then use the function atoi on the result
This way you could take any size of string you want from the charArray, without manually having to calculate the number
Example (based on your code, assuming you want to keep the charArray as is without changing it) :
int main(void)
{
char charArray[6]="12345";
char newcharArray[5];//one char less than charArray
strncpy(newcharArray,charArray,4);
printf("%d\n",atoi(newcharArray));
}
you can also use alternative methods.
Please check: Converting string to integer C
You can also use strtoumax() function.
see the example : http://pic.dhe.ibm.com/infocenter/zos/v1r12/index.jsp?topic=%2Fcom.ibm.zos.r12.bpxbd00%2Fstrtoumax.htm

Simple Concatenation in C

I'm not good in C, top of that I'm doing after very long, I need to do a very simple thing:
char code[]="aasd";
char *rmessage="";
strcat(rmessage,code[0]);
I simply want to concatenate the content of index 0 of array code to rmessage.
You need to ensure there is enough space in rmessage to store the result of the concatentation. You can use strncat to specify the number of characters to copy from a string:
char code[] = "aasd";
char rmessage[1024] = "";
strncat(rmessage, code, 1);
or, in this case, just assign the first character of rmessage:
rmessage[0] = code[0];
Not coding in C for long time.I think the syntax is just correct.
int sz=10; // sz = # number of chars you want to store + 1 , i assumed 9 characters will be stored at max.
char code[] = "aasd";
char *rmessage = malloc(sz*sizeof(char));
rmessage[0]=code[0];
rmessage[1]=NULL;
*Remember to deallocate the memory allocated to rmessage after your job is done.
free(rmessage);

Resources