Conversion of decimal to string - c

I'm trying to convert a decimal value into a string. I use the STM32CubeIDE IDE but am getting an error like 'Invalid binary operator'. I'm able to set &n to the decimal value 3695. I need to convert that into a string. How would I do that?
void main()
{
uint8_t TxArr;
uint16_t Data;
int a[10];
int i;
while (1)
{
HAL_I2C_Master_Transmit(&hi2c1,0x16, &TxArr, 1, 1000);
HAL_I2C_Master_Receive(&hi2c1, 0x17, &Data, 2, 1000);
for(i=0;i<4;i++)
{
a[i]=Data%10+0x30; //value in Data is 3695.
Data=Data/10;
HAL_UART_Transmit(&huart3, a[i], 11, 100);
HAL_Delay(300);
}
}

The error is produced by:
n = n / 10;
What this would do if n was a pointer (int* n) is that it would repoint n to a location one tenth the original number. You will need to begin using normal array operators if you want your code to work properly.
The second problem you have is the following:
You declare n as a array of 10 integers of type and with int.
int n[10];
Then in your for loop you try to do this:
n > 0;
This is an invalid operation as n wil decay into a pointer and as such the address of your array is compared to 0. This will always evaluate as TRUE!
A good way to convert a integer to a string (char array) is this answer.
In your sitaution that would be
int yourToBeConvertedNumber;
char str[INT_MAX]; // or any other reasonable upper bound you have set for the input data.
snprintf(str, sizeof(str), "%d", yourToBeConvertedNumber);

Generally speaking, to convert an integer to a string, you can use the sprintf function. It should be available in newliband even newlib-nano standard C libraries.
However my guess here is that you have an array of integers where each element is a number between 0 and 9 ?
If this is true you have several issues: you seem to handle the variable n like an integer and not an address. Also your string should be one element longer and composed of chars.
You may do something like this:
char a[11];
for(i=0;i<10;i++)
{
a[i]=n[i]%10 +'0';
}
a[11]='\0';

Related

Using strlen() with Array Integers or Float [duplicate]

This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 3 years ago.
Is there a way, I can use of strlen() to find the length of the arrays, instead of specifying in the loop.
First Code: Working With x < 4 Which is the size of the array of temps[4].
#include <stdio.h>
#include <string.h>
int main(){
float temps[4] = {72.5, 73.4, 74.7, 75.2};
int x;
printf("Local Temperatures\n");
for(x = 1; x < 4; x++){
printf("Station %d: %.1f\n",x,temps[x]);
}
}
My Second Code, Not Working, But Looking At What, I Am Trying To achieve with strlen() to find the size of the array.:
#include <stdio.h>
#include <string.h>
int main(){
float temps[4] = {72.5, 73.4, 74.7, 75.2};
int x;
float size;
size = temps;
printf("Local Temperatures\n");
for(x = 1; x < strlen(size); x++){
printf("Station %d: %.1f\n",x,size[x]);
}
}
strlen is effectively an optimized version of the following:
size_t len = 0;
const char *p = s;
while (!*p) {
++len;
++p;
}
You can easily adapt that.
size_t len = 0;
const float *p = s;
while (*p != 0.0) {
++len;
++p;
}
Of course, that means you need a sentinel value just like you had for the string.
float temps[] = { 72.5, 73.4, 74.7, 75.2, 0.0 };
While you can use a value other than 0.0 as your sentinel value, using a sentinel value might not be desirable, so you might not really want to take the same approach as one does for strings.
For an array (as opposed to a pointer), you can use the following to determine the number of elements in the array:
sizeof(a)/sizeof(*a)
That means you can use the following to determine the number of elements in temps:
sizeof(temps)/sizeof(*temps)
Simple method is to get the size of a array is by sizeof(temps)/sizeof(temps[0])
something like,
for(x = 0; x < sizeof(temps)/sizeof(temps[0]); x++){
printf("Station %d: %.1f\n",x,temps[x]);
}
Note: In your snippet array access is done from 1 to (size) instead 0 to (size-1) which is out of bound access.
Short answer: no.
strlen expects an argument of type char *, which points to the first character of a string, which is a sequence of character values including a zero-valued terminator. strlen returns the number of characters before the terminator:
/**
* A naive implementation of strlen. Actual implementations
* are a little more clever.
*/
size_t strlen( const char *str )
{
size_t count = 0;
while( str[count] )
count++;
return count;
}
The important thing to remember is that strlen returns the length of the string, not the size of the array containing the string. If you have something like
char foo[1024] = “bar”;
the strlen( foo ); returns 3.
If you tried to pass an integer or floating point array to strlen the compiler would yell at you because of the wrong argument type. You could work around this by casting the argument to char *, but you would still likely get a wrong answer, not only because integer and float types are multiple chars wide, but also because such a value may have an embedded zero-valued byte. For example, the integer value 16 is represented as the bytes 0x00, 0x00, 0x00, 0x10. If that’s the first element of your integer array, then strlen would return 0 on a big-endian platform and 1 on a little-endian platform.
If you defined the array, then you know how big it is. If you’re writing a function that receives an array argument, then you must either also receive the size as a separate argument, or you must rely on the presence of a sentinel value in the array.
Just do this to get the length of your float array,
int main()
{
float ar[4] = {1.1,1.2,1.3,1.4};
float b;
printf("Array Size : %d\n",sizeof(ar)/sizeof(b));
return 0;
}
You'll get the total number of element of your array , which you can use further in a loop to print the elements of array.
Note: Do not Use sizeof in case of pointers.
strlen() takes a "const char *" type value as argument. So it cannot be used with integer or float arrays.

Looking at and using individual bytes in void pointers in C [duplicate]

This question already has answers here:
What does void* mean and how to use it?
(10 answers)
Closed 5 years ago.
I'm trying to make a calculator that takes a void pointer called yourVal, look at the first byte and decide if it's a '*' or '/'. Based on the sign, i multiply bytes 3+4, 5+6, and 7+8. say i have *1234567. I multiply 23 * 45 * 67. With the division, I divide byte 5(45) by byte 3(23). I'm a novice with pointers in C, and I really have no idea how to even set a value to a void pointer. When I do the following in main
void *yourVal;
*yourVal = "*1234567";
printf("%s\n", yourVal);
I'm not able to dereference a void pointer. But I tried with a char pointer, and I have the same issue.
This is my code for the calculator function. Based on whether I use printf or not, I get different results.
int calculator(void *yourVal){
char *byteOne;
short int *byteThree, *byteFive, *byteSeven;
int value;
byteOne = (char *)yourVal;
byteThree = (short int *)yourVal+2;
byteFive = (short int *)yourVal+4;
byteSeven= (short int *)yourVal+6;
if(*byteOne == '*') {
value = *byteThree * *byteFive * *byteSeven;
printf("You multiplied\n");
}
else if(*byteOne == '/') {
if (*byteThree == 0) {
value = 0xBAD;
printf("Your input is invalid\n");
}
else {
value = *byteFive / *byteThree;
printf("You divided\n");
}
}
else {
value = 0xBAD;
printf("Your input is invalid\n");
}
}
The division isn't working at all, and the multiplication only grabs one digit. Any tips would be appreciated. I looked at various sources but I'm not seeing how to work with void pointers efficiently. Also, I can't use any library functions other than printf, and this is a school assignment, so try not to give too many spoilers or do it for me. We were given one hint, which is to cast yourVal to a structure. But I'm lost on that. Thanks
byteOne = (char *)payload;
byteThree = (short int *)yourVal+2;
byteFive = (short int *)yourVal+4;
byteSeven= (short int *)yourVal+6;
This doesn't do what you think it does. If you want to read the numbers at these positions, you need to do something like.
char* Value = yourValue;
unsigned byteOne, byteThree, byteFive, byteSeven;
byteOne = Value[0] - '0';
byteThree = Value[2] - '0';
byteFive = Value[4] - '0';
byteSeven = Value[6] - '0';
What I have done here is read the byte at that position and subtract the ASCII value of '0' to get the numerical value of that character. But again this will work only for a single character.
If you need to read more characters you will have to use library functions like sscanf or atoi.
The void pointer adds no functionality you need to solve this problem, it just complicates things. Use a char pointer instead.
"*1234567" is a string, not an array of integers. You cannot treat it as an array of integers. Each character would have to be converted to an integer before you do arithmetic. The easiest way to do that is to subtract by the ASCII character '0'.
"...i multiply bytes 3+4..." When counting bytes, you always start at 0. In the string "*1234567", the 2 is the byte with index 2 not 3.
"Based on the sign, i multiply bytes 3+4, 5+6, and 7+8. say i have *1234567. I multiply 23 * 45 * 67. With the division, I divide byte 5(45) by byte 3(23)"
I fail to see how this algorithm makes any sense. What is the 1 there for? Why aren't you using some conventional formatting such as prefix, postfix or just plainly typed-out equations?
Example:
int calculator (const char* yourVal)
...
int byte2 = yourVal[2] - '0';

unsigned char table length

I declared a table of unsigned char as follow:
unsigned char buf[10]={'1','5',0x00,'8'};
in order to know the number of elements of this table i implemented this function
int tablength(unsigned char *buf)
{
int i=0;
for (i=0;buf[i];i++)
;
return i;
}
However this function don't give me the right result when the buffer contains 0 in the middle .Sizeof don't give me the right result since it returns 10 in this case i can't neither use strlen since this is a table of unsigned char.
Do you have any idea to improve this function or any predefined function that help me solve my problem (the result that i 'am waiting for is 4)
Technically, since you declared a statically allocated array of 10 elements, the size of the array is 10. Even though you may not have initialized every element, there is something filling that space. C++ cannot determine whether the value in the array means anything or not.
After
unsigned char x[10] = {1, 2, 3};
the variable x (an array) has 10 elements, the first three initialized to 1, 2 and 3 and all the others initialized to 0. In other words that definition is absolutely identical to
unsigned char x[10] = {1, 2, 3, 0, 0, 0, 0, 0, 0, 0};
An array in C and C++ is just a fixed area of memory and doesn't include a counter of how many "interesting" elements are there.
If you are looking for a container with a variable number of elements consider instead std::vector (C++ only). With that std::vector::size() returns the current number of elements in the container.
If you need the array to contain exactly the number of elements you've specified, just declare it without a specific size:
unsigned char buf[]={'1','5',0x00,'8'};
cout << sizeof(buf); // should be 4
If you want to store a variable amount of data (in C++) use std::vector instead of an array.
Otherwise you'll need to keep track of the number of valid elements yourself. There's nothing in the language that will do it for you.
Compilers cannot know how you would like to use an array instance.
Therefore you must follow the language's semantics. By declaring your array globally or locally, but with the storage class specifier static you are initializing every element to 0 on default and your function will work.
0x00 is false. 0x00 (which same as 0x0) is a hex number representing 0 (false). This is where your counting loop will stop at - the 3rd element.
Another thing you can do is declare your array with non-fixed size.
unsigned char buf[]={'1','5',0x00,'8'};
In that case, the sizeof operator works as expected.
Because that way, you will have an array of 4 elements.
strlen() obviously won't work as it is designed to work with strings, not a buffer.
As for a function that counts on a smarter way:
size_t arrcnt (unsigned char source[], size_t size)
{
size_t i;
for(i = size; i >= 0 && !source[i]; i--);
return i + 1;
}
Usage:
printf("size of buf: %u", arrcnt(buf, sizeof(buf));
buf[i] evaluates to false when buf[i] contains 0.
You cannot do what you want unless you know one value which can never occur in your array between 0 to UCHAR_MAX (255). Say the value is 255, then you first preinitialize the full array to 255 before you start filling it up.
memset(buf, 255, sizeof(char) * sizeof(buf));
Then you fill other elements like you want and then you can use the following
for(i = 0; buf[i] != 255, ++i)
try putting :
for(int i=0;buf[i]!= 0;i++)
count++;
return count;

Translate string to number

I am looking for a way to take a string and check 3 possibilities.
Digit and thus converts it to a signed int (not a long)
Is a symbolic representation previously defined at runtime, and converts it to a signed int
Neither
The "symbolic representation" will be basically like an associative array that starts at 0 elements and expands as more symbols are added. For example lets say for instance that C had associative arrays (I wish) with this peusdocode:
symbol_array['q'] = 3;
symbol_array['five'] = 5;
symbol_array['negfive'] = -5;
symbol_array['random294'] = 28;
signed int i;
string = get_from_input();
if(!(i = convert_to_int(string))) {
if(!(i = translate_from_symbol(string))) {
printf("Invalid symbol or integer\n");
exit(1);
}
}
printf("Your number: %d\n, i);
The idea being if they entered "5" it would convert it to 5 via convert_to_int, and if they entered "five" it would convert it to 5 via translate_from_symbol. As what I feel may be hardest is if they entered "random294" it wouldn't convert it to 294, but to 28. If they entered "foo" then it would exit(1).
My general questions are these: (Instead of making multiple posts)
When making convert_to_int I know I shouldn't use atoi because it doesn't fail right. Some people say to use strtol but it seems tedious to convert it back to a non-long int. The simplistic (read: shortest) way I've found is using sscanf:
int i;
if ((sscanf(string, "%d", &i)) == 1){
return i;
}
However, some people look down on that even. What is a better method if not sscanf or converting strtol?
Secondly, how can I not only return an integer but also know if it found one. For example if the user entered "0" then it would return 0, thus setting off my FALSE in my if statement. I had considered using -1 if not found but since I am returning signed int's then this also suffers from the same problem. In PHP I know for example with strpos they use === FALSE
Finally, is there any short code that emulates associate arrays and/or lets me push elements on to the array in runtime?
First, you might want to revise your syntax and set the keyword apart from the operand, i.e. "neg five" instead of "negfive". Otherwise your symbol lookup for the keywords has to consider every prefix. ("random294" might be okay if your keywords aren't allowed to have digits in them.)
Sure, sscanf tells you whether you found a decimal in the return value and writes that decimal to a separate int, which is nice, but you'll have to watch out for trailing characters by checking that the number of characters read equals the length of your string with the %n format. Otherwise, sscanf will consider 5x as legal decimal number. strtol also returns a pointer to the location after the parsed decimal number, but it relies too much on checking err for my taste.
The fact that strtol uses long integers shouldn't be an issue. If the input doesn't fit into an int, return INT_MAX or INT_MIN or issue an error.
You can also easily write a wrapper function around sscanf or strtol that suits your needs better. (I know I'd like a function that returns true on success and stores the integer via a pointer argument, sscanf style, where success means: no trailing non-digit characters.)
Finally, about the associative arrays: There is no short code, at least not in C. You'll have to implement your own hash map or use a library. As a first draft, I'd use a linear list of strings and check them one by one. This is a very naive approach, but easy to implement. I assume that you don't start out with a lot of symbols, and you're not doing a lot of checks, so speed shouldn't be an issue. (You can sort the array and use binary search to speed it up, but you'd have to re-sort after every insertion.) Once you have the logic of your program working, you can start thinking about hash maps.
Something like this should do your job:
#include <stdio.h>
#include <string.h>
struct StringToLongLookUp {
char *str;
char *num;
};
struct StringToLongLookUp table[] =
{
{ "q" , "3" },
{ "five" , "5" },
{ "negfive" , "-5" },
{ "random294", "28" }
};
int translate_from_symbol(char **str)
{
int i;
for(i = 0; i < (sizeof(table) / sizeof(struct StringToLongLookUp)); i++)
{
if(strcmp(*str, table[i].str) == 0)
{
*str = table[i].num;
return 1; // TRUE
}
}
return 0; // FALSE
}
int main()
{
char buf[100];
char *in = buf;
char *out;
int val;
scanf("%s", in);
translate_from_symbol(&in);
val = strtol(in, &out, 10);
if (in != out)
{
printf("\nValue = %d\n", val);
}
else
{
printf("\nValue Invalid\n");
}
}
Of course, you get a long, but converting that to int shouldn't be an issue as mentioned above.

invalid conversion from 'char' to 'int* in C

I have the following arrays:
int A[] = {0,1,1,1,1, 1,0,1,0,0, 0,1,1,1,1};
int B[] = {1,1,1,1,1, 1,0,1,0,1, 0,1,0,1,0};
int C[] = {0,1,1,1,0, 1,0,0,0,1, 1,0,0,0,1};
//etc... for all letters of the alphabet
And a function that prints the letters on a 5x3 LED matrix:
void printLetter(int letter[])
I have a string of letters:
char word[] = "STACKOVERFLOW";
and I want to pass each character of the string to the printLetter function.
I tried:
int n = sizeof(word);
for (int i = 0; i < n-1; i++) {
printLetter(word[i]);
}
But I get the following error: invalid conversion from 'char' to 'int*'
What should i be doing?
Thanks!!
Behind the parameter type error there is a deeper issue: you lack the mapping between a char and the corresponding int[].
Redefining printLetter as
void printLetter(char letter)
satisfies the compiler, but doesn't solve your problem per se. Whether inside or outside printLetter, you need to get the corresponding int[] for a given char.
A simple brute-force way to achieve this would be to use a switch, but a better way is to use a second array, i.e. something like this:
void printLetter(char letter) {
static int* charToMatrix[] = { A, B, C, ... };
int* matrixToPrint = charToMatrix[letter - 'A'];
// print the matrix
}
Note that this is an example - I don't have access to a C compiler right now, so I can't guarantee it works straight away, but hopefully it illustrates the point well enough. It also lacks bounds checking, so it accesses memory in strange random places, possibly resulting in a crash, if you attempt to print an "unknown" character.
This solution is supposed to work for the uppercase letters; if you need to print lowercase letters or other characters as well, you might prefer going with an array of 256 elements, where only the elements at indexes corresponding to the "known" matrices are filled, and the rest is set to NULL.
You cannot so easly transform the 'a' from "stackoverflow" to the A - the array of ints. You can define all the arrays that represent a letter in one single letter and get them by the convertion of your letter to int.
What you need to do is convert from a character to one of your arrays. So when you have the letter 'A', you'll want to use array A. The easiest way to do this is via lookup table.
int *lookup[256]; // assuming ASCII
memset(lookup, 0, sizeof(lookup));
lookup['A'] = A;
lookup['B'] = B;
...
Then when you have a character, you can get the proper array:
void printletter(char c);
{
int *data = lookup((unsigned char)c);
// In case you get a letter that you don't know how to display
if (data != NULL)
{
// display with data
}
}
Instead of building up your array at runtime, you can also build up your array at compile time although it will be a bit harder as you will need to manually put in NULL pointers.
int *lookup[256] = {
NULL, // you need a total of 65 NULL's
NULL,
...
A, // so this is at the correct position
B,
C,
...
};
The function is declared as void printLetter(int letter[]), which means it takes a pointer to an array of ints. On the other hand, word is an array of chars, and word[i] is a char, which is not at all the right type. If printLetter() is really just supposed to print a single character, you should change its argument to be a char.
void printLetter(int letter[])
should be
void printLetter(char letter)
Because: word is a char[] word[i] is a character.

Resources