Hello I´m fairly new to C programming and i want to convert a char array looking like
char numberlist[]="9,8 2,3 5,4 2,7 1,3";
to a float that would be 9.8 ,i used
float a;
a=atof(numberlist);
printf("%.1f\n",a);
but that gave me 9.0 in return because it is 9,8 instead of 9.8 in the char array. How could i easily fix that, without touching the char array?
Thanks in advance :)
For example
char numberlist[]="9,8 2,3 5,4 2,7 1,3";
float convertFirstNumber(const char *str, char delim)
{
char z[256];
size_t index = 0;
while(*str && *str != delim)
{
if(*str == ',') z[index++] = '.';
else z[index++] = *str;
str++;
}
z[index] = 0;
return atof(z);
}
int main()
{
printf("%.1f\n",convertFirstNuber(numberlist, ' '));
}
This can be done with int sscanf(const char *restrict s, const char *restrict format, ...); and atof i have chossed sscanf to show u different approach. you can replace it with atof if you wish.
int main(){
float f, resd;
int i = 0;
char numberlist[]="9,8 2,3 5,4 2,7 1,3";
sscanf(numberlist,"%f",&f);
while(numberlist[i] != ','){
++i;
}
sscanf(&numberlist[i],",%f",&resd);
printf("%f\n", resd);
printf("%f",f+resd/10.0);
return 0;
}
If your string uses a comma as decimal point, you could set the locale to a useful value before parsing:
/* Set number locale to german */
setlocale(LC_NUMERIC, "de_DE.utf8");
double a; /* Never use floats */
sscanf("3,14", "%lf", &a);
/* It is better to not hardcode "C" but use the locale saved before the
previous `setlocale` */
setlocale(LC_NUMERIC, "C");
/* Should print "3.14" */
printf("%lf\n", a);
Just remember that setlocale has issues with multithreaded software. And you should reconsider if you really want to store your data with comma as the decimal point.
Adam gave a good answer.
You can also iterate the string and create the number manually.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
char numberlist[] = "9,8 2,3 5,4 2,7 1,3";
int main() {
int len = strlen(numberlist);
int total = 0;
int count = 0;
for(int i = len; i >= 0; i--){
char c = numberlist[i];
if(isdigit(c)){
int number = atoi(&c);
total += round(pow(10, count)) * number;
count++;
}
}
float value = total / round(pow(10, count-1));
printf("%.2f\n", value);
}
Related
I have for example a string (mathematical equation in postfix notation) that looks like this: The numbers are 5.33,5.32,6.33,3.22
5.335.32*6.333.22++
I'm looking to make it into prefix notation but simply reversing the string won't work due to the fact it has to retain the value of the number.
I've thought of doing a normal character by character swap in a for loop, and when encountering a digit make that into a substring and place it on afterwards but I haven't gotten it to work properly and now I'm stuck.
My end-goal is to make a binary expression tree out of that, so if there's an easier way than doing this also please let me know.
A stack-based approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *postfix_to_prefix(const char *string) {
char operator, *stack[1024];
int s = 0, number, fraction;
const char *tokens = string;
while (1) {
if (sscanf(tokens, "%1d.%2d", &number, &fraction) == 2) {
stack[s] = malloc(sizeof("1.00"));
(void) sprintf(stack[s++], "%4.2f", number + (fraction / 100.0));
tokens += strlen("1.00");
} else if (sscanf(tokens, "%c", &operator) == 1) {
char *operand1 = stack[--s];
char *operand2 = stack[--s];
stack[s] = malloc(strlen(operand1) + strlen(operand1) + sizeof(operator) + sizeof('\0'));
(void) sprintf(stack[s++], "%c%s%s", operator, operand1, operand2);
free(operand1);
free(operand2);
tokens += sizeof(operator);
} else {
break;
}
}
return stack[--s];
}
int main() {
const char *string = "5.335.32*6.333.22++";
printf("%s\n", string);
char *inverted = postfix_to_prefix(string);
printf("%s\n", inverted);
free(inverted);
return 0;
}
OUTPUT
> ./a.out
5.335.32*6.333.22++
++3.226.33*5.325.33
>
This is a bare bones implementation with no real error checking nor other finishing touches. You'll want to check that non-communitive operations like subtraction and division come out with the operands in the correct order and reverse them if not.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char exp[] = "5.335.32*6.333.22++";
size_t len = strlen(exp);
char temp[len];
char *p = temp;
for(int i = len-1; i >= 0; ){
if(isdigit(exp[i])){
memcpy(p, &exp[i-4+1], 4);//all number have a length of 4
p += 4;
i -= 4;
} else {
*p++ = exp[i--];//length of op is 1
}
}
memcpy(exp, temp, len);//Write back
puts(exp);//++3.226.33*5.325.33
return 0;
}
#include <stdio.h>
#include <string.h>
int add(char s[])
{
char p[3];
int i=0, j=0, sum=0;
for(i=0;s[i]!='\0';i++)
{
if(isdigit(s[i])&&isdigit(s[i+1])&&isdigit(s[i+2])&&!isdigit(s[i+3])&&!isdigit(s[i-1]))
{
p[0]=s[i];
p[1]=s[i+1];
p[2]=s[i+2];
sum+=atoi(p);
}
}
return sum;
}
Above I tried writing the code to add only three digit numbers within the string text but it is not working. Can't figure out what the problem is.
If I understand you want to add the sum of the first 3 digits in the string, then you are definitely going about it the hard way. After passing the string to your function, simply assign a pointer to the string and check each char in the string. If the char is a digit, then add the digit to sum. After you have found your 3 digits, simply return the sum. (you may as well make your function general to return the sum of any number of digits you choose).
Note: you must convert the ascii value of the digit to it numeric value before adding it to sum. (i.e. ascii char 9 - '0' is numeric 9, etc..) (See the ascii character values )
Here is a short example that adds the first 3 digits found in the string using the method above. If you have questions or different needs, just let me know.
#include <stdio.h>
#include <string.h>
int add_ndigits (const char *s, size_t ndigits)
{
const char *p = s; /* pointer to string */
int sum = 0;
size_t count = 0;
while (*p) { /* for each char in string */
if (*p >= '0' && *p <= '9') { /* check if it is a digit */
sum += *p - '0'; /* if so add value to sum */
count++; /* increment digit count */
if (count == ndigits) /* if count = ndigits break */
break;
}
p++;
}
return sum; /* return the sum of the first ndigits in string */
}
int main (void) {
char string[] = "this is 1 string with 2 or 3 more digits like 1, 2, 7, etc.";
int sum3 = add_ndigits (string, 3);
printf ("\n The sum of the first 3 digits in 'string' is: %d\n\n", sum3);
return 0;
}
Output
$ ./bin/add3string
The sum of the first 3 digits in 'string' is: 6
Simple alternative
int add(char s[]) {
int c = 0, ans = 0;
for (const char * d = s; *d; ++d)
if (isdigit(*d) && c < 3) {
ans += (*d - '0');
++c;
}
return ans;
}
char p[3] can not hold 3 characters. You need to have extra byte for the null terminator.
You can declare it as char char p[4] and do memset to avoid confusion with null termination as following:
`memset(p,'\0',sizeof(p));`
Let me know, if you have any concerns.
#include <stdio.h>
#include <string.h>
int add(char s[])
{
char *p;
unsigned sum=0;
do {
while(!isdigit(*s) && *s) /* Skip nondigits except \0 */
++s;
p=s;
if(isdigit(*s) && isdigit(*++s) && isdigit(*++s))
if(isdigit(*++s)) /* more than 3 digits? */
while(isdigit(*++s)) /* then skip rest of digits */
{}
else {
if(*p == '0') { /* prevent atoi from reading octal */
if(*++p == '0')
++p;
}
sum += atoi(p);
}
} while(*s);
return sum;
}
EDIT: I'm soo stupid. I never liked the
if(isdigit(p[0]=s[i]) && isdigit(p[1]=s[++i]) && isdigit(p[2]=s[++i]))
to begin with.
I want to write my own function in C for various reasons that converts an int to a string of decimals, just like sprintf.
Example:
int number = 254;
char string[10];
sprintf(string, "%d", number);
The string should look like this after the function I want to write:
[0] 2
[1] 5
[2] 4
[3] '\0'
Just to clarify even further, I want to program the actual convertion of an int to a string of chars. I don't want to use sprintf or itoa etc to do it. I want to know how it is done and be able to program it myself and do small adjustments to it.
Additional clarification:
I don't want to use itoa or sprintf, but pretty much program these myself.
#include <stdio.h>
#include <stdlib.h>
int i2a(char *s, int n){
div_t qr;
int pos;
if(n == 0) return 0;
qr = div(n, 10);
pos = i2a(s, qr.quot);
s[pos] = qr.rem + '0';
return pos + 1;
}
char* my_itoa(char *output_buff, int num){
char *p = output_buff;
if(num < 0){
*p++ = '-';
num *= -1;
} else if(num == 0)
*p++ = '0';
p[i2a(p, num)]='\0';
return output_buff;
}
int main(void){
int number = -254;
char string[12];
printf("%s", my_itoa(string, number));
return 0;
}
int number = 254;
int back=0,i=0;
char ch='\0';
char string[10];
for(i=0;(number/10)==0;i++){
back=number%10;
ch=(back*pow(10,i)+48);
string[i]=ch;
}
divide number per 10
get the rest( with % ) the rest is the digit you want starting from the right
cast the digit to char +48(ascii 0)
add to string
I am using sprintf for string formation in C.
I need to insert '+' and '-' sign before float value.
This positive and negative signs are inserted by checking a flag after that i insert the float value.
Now i want to make this whole number in right alignment along with positive or negative sign.
Currently this is my formatted string:
+300.00
-200.00
+34.60
I want output like following,
+300.00
+233.45
-20.34
I have written following code:
char printbuff[1000], flag = 1;
double temp=23.34, temp1= 340.45;
sprintf(printBuff, "%c%-lf\n%c%-lf",
(Flag == 1) ? '+' : '-',
temp,
(Flag == 1) ? '+' :'-',
temp1);
I am getting following output:
+23.34
+340.45
Instead of the desired:
+23.45
+340.45
How can I do this?
use like this
sprintf(outputstr, "%+7.2f", double_number);
E.g.
#include <stdio.h>
#include <string.h>
#include <math.h>
void output_string(char output_buffer[], double nums[], size_t size){
/* use '+' flag version
int i,len=0;
for(i=0;i<size;++i)
len += sprintf(output_buffer + len, "%+7.2f\n", nums[i]);
*/ //handmade version
int i, len=0;
for(i=0;i<size;++i){
char sign = nums[i] < 0 ? '-' : '+';
char *signp;
double temp = abs(nums[i]);
len += sprintf(signp = output_buffer + len, "%7.2f\n", temp);
signp[strcspn(signp, "0123456789")-1] = sign;//The width including the sign is secured
}
}
int main(){
double nums[] = {
+300.00,
-200.00,
+34.60,
+300.00,
+233.45,
-20.34
};
char output_buffer[1024];
int size = sizeof(nums)/sizeof(*nums);
output_string(output_buffer, nums, size);
printf("%s", output_buffer);
return 0;
}
int main()
{
char s[100];
double x=-100.00;
sprintf(s,"%s%f",x<0?"":"+",x);
printf("\n%s",s);
x = 1000.01;
sprintf(s,"%s%f",x<0?"":"+",x);
printf("\n%s",s);
return 0;
}
Here is the code.
Its O/p is ::
-100.000000
+1000.010000
you need a separate buffer, in which you sprintf your number with your sign, and that resulting string you can sprintf into the rightjustified resultbuffer.
You need something like:
char str[1000];
double v = 3.1415926;
sprintf(str, "%+6.2f", v);
The + indicates "show sign".
A more complete bit of code:
#include <stdio.h>
int main()
{
double a[] = { 0, 3.1415, 333.7, -312.2, 87.8712121, -1000.0 };
int i;
for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
{
printf("%+8.2f\n", a[i]);
}
return 0;
}
Output:
+0.00
+3.14
+333.70
-312.20
+87.87
-1000.00
Obviously, using sprintf, there would be a buffer involved, but I believe this shows the solution more easily.
I have a hexadecimal value "F69CF355B6231FDBD91EB1E22B61EA1F" in a string and I am using this value in my program by hardcoding the value in an unsigned char variable like this:
unsigned char a[] = { 0xF6 ,0x9C ,0xF3 ,0x55 ,0xB6 ,0x23 ,0x1F ,0xDB ,0xD9 ,0x1E ,0xB1 ,0xE2 ,0x2B ,0x61 ,0xEA ,0x1F};
Is there any function or any other method by which I can take the value from a string and put it into an unsigned variable in the hexadecimal format by packing it?
#include <stdio.h>
#include <ctype.h>
int hctoi(const char h){
if(isdigit(h))
return h - '0';
else
return toupper(h) - 'A' + 10;
}
int main(void){
const char cdata[]="F69CF355B6231FDBD91EB1E22B61EA1F";
unsigned char udata[(sizeof(cdata)-1)/2];
const char *p;
unsigned char *up;
for(p=cdata,up=udata;*p;p+=2,++up){
*up = hctoi(p[0])*16 + hctoi(p[1]);
}
{ //check code
int i;
for(i=0;i<sizeof(udata);++i)
printf("%02X", udata[i]);
}
return 0;
}
You can translate a hexadecimal value in a string into a value using sscanf. If you want an array of values, then you could write a function to split up the input string into two character segments and use sscanf to convert each piece. (I haven't done C for an eternity so I don't know if that's a good way to do it.)
If it's for 32 single hex-values (16 bytes, 128bit) only then you might take look at the methods provided by libuuid.
libuuid is part of the e2fsprogs package. Anyhow some linux distros, Debian for example, ship libuuid as a separate package. To use the Debian package for your developement you also need to look here.
Check this answer for doing this stuff in c++ using sscanf().
For c, it would be something like this:
char *str = "F69CF355B6231FDBD91EB1E22B61EA1F";
char substr[3] = "__";
unsigned char *a = NULL;
len = strlen(str);
a = malloc(sizeof(unsigned char)*(len/2)+1);
for ( i = 0; i < len/2; i++) {
substr[0] = str[i*2];
substr[1] = str[i*2 + 1];
sscanf( substr, "%hx", &a[i] );
}
free(a);
Introduce auxiliary functions data_length and data_get to easily iterate over your data. The following program dumps unpacked unsigned chars on stdout, one per line:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/* htoi(H)
Return the value associated to the hexadecimal digit H. */
int
htoi(char h)
{
int a = -1;
if(isdigit(h))
{
a = h - '0';
}
else
{
a = toupper(h) - 'A' + 10;
}
return a;
}
/* data_length(D)
The length of the data stored at D. */
int
data_length(const char* d)
{
return strlen(d) / 2;
}
/* data_get(D, K)
Return the K-th unsigned char located encoded in d. */
unsigned char
data_get(const char *d, int k)
{
return htoi(d[2*k]) * 0x10 +
htoi((d+1)[2*k]);
}
int
main()
{
const char cdata[]="F69CF355B6231FDBD91EB1E22B61EA1F";
for(int i = 0; i < data_length(cdata); ++i)
{
printf("0x%02hhx\n", data_get(cdata, i));
}
return EXIT_SUCCESS;
}