BratBart
BratBart

Reputation: 407

C dynamic data specifiers

I want to write something like the following code, but I failed. I want to assign dynamic number of chars from array y to x. This number will be defined later. Here is a simple example of what I mean.

#include<stdio.h>
int main() 
{
    int x=0;
    char y[]={'5','4'};
    int z=1;
    sscanf(y,"%zi",&x);       
    printf("%i",x);         //Each time value of x=0
    sscanf(y,"%1i",&x);    //I want to make this 1 dynamic "int z"
    printf("%i",x);       //Here x value =54.
    return 0;
}

Upvotes: 1

Views: 96

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 754410

Succinctly, you can't do what you want directly.

With printf(), you can use this, where all three variables are of type int and the widths will be read from x and y:

printf("%*.*d", x, y, z);

However, the scanf() family of functions provides nothing analogous. A * means 'assignment suppression' in scanf(). Note that in C99 and beyond, %zi tells scanf() that the type of the pointer argument is size_t *. This probably accounts for why you got 0 as a result; sscanf() was writing out of bounds for the variable you passed to it.

Your best bet is to use snprintf() to create the format string you want used by scanf().

int x;
char y[] = { '5', '4' };
int z = 1;
char format[16];
snprintf(format, sizeof(format), "%%%di", z);
if (sscanf(y, format, &x) != 1)
    …handle error…
printf("%d\n", x);    // Will print 5

Note that if z is 1 or 2, this works OK; if z is larger, then y is not a null-terminated string and you run into undefined behaviour. If z is zero or negative, you run into problems too.

Upvotes: 3

ameyCU
ameyCU

Reputation: 16607

If you see , you declared and initialized array like this -

 char y[]={'5','4'};

y is not a string because it is not terminated using '\0' , so you need to explicitly add nul terminater . As sscanf will take a c-style string as first argument.

 char y[]={'5','4','\0'};   // or char y[]="54";

Working demo

Upvotes: 1

Related Questions