0

I want to set a placeholder value (type int) of a path:

/sys/class/gpio/gpio%d/value => /sys/class/gpio/gpio33/value

The inserted value is maximum 99 and minimum 1. Because I do not want any empty chars in my path I would like to have the buffer size determined automatically.

This is why I thought of asprintf() which does this for strings unfortunately it does not work with integers.

#define GPIO_PATH_VALUE "/sys/class/gpio/gpio%d/value"

char * path;

asprintf(path, GPIO_PATH_VALUE, 4);
asprintf(path, GPIO_PATH_VALUE, 67);

Is there a function similar to asprintf() which works with integers?

Bodo

4
  • @SIGSEGV you mean? Could you provide an example? Commented Jun 18, 2013 at 9:03
  • 1
    Your code works for me by making first parameter to asprintf as &path. Linux/gcc-4.7 Commented Jun 18, 2013 at 9:04
  • 1
    first argument type char ** Commented Jun 18, 2013 at 9:05
  • You can try using strcat to populate the 'path'? Would it be very inefficient? Commented Jun 18, 2013 at 9:06

2 Answers 2

2

try this asPrintf() takes char ** as arguement, see this http://linux.die.net/man/3/asprintf

#define GPIO_PATH_VALUE "/sys/class/gpio/gpio%d/value"

char * path;

asprintf(&path, GPIO_PATH_VALUE, 4);
asprintf(&path, GPIO_PATH_VALUE, 67);

As asPrintf() do malloc() inside function, in this function path wont be pointing to malloced memory address, so you need to send address of path so that asPrintf() changes the path and that will be pointing to malloced address.

Sign up to request clarification or add additional context in comments.

Comments

2

As asprintf() is a GNU extension, other people facing this problem might want to avoid it.

Instead, it could be done such as

#define GPIO_PATH_VALUE "/sys/class/gpio/gpio%d/value"

char * path;

path = malloc(strlen(GPIO_PATH_VALUE) + 5);
// error checking needed!

sprintf(path, GPIO_PATH_VALUE, 4); // better snprintf?
// or
sprintf(path, GPIO_PATH_VALUE, 67);

path = realloc(path, strlen(path)+1);
// no error checking needed, as we definitely shrink or nop, not extend.

if it is clear that GPIO_PATH_VALUE stays that simple.

If it gets more complicated, you can do

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

char * vbsprintf(const char * format, va_list ap)
{
    va_list ap2;
    va_copy(ap2, ap);
    int len = vsnprintf(NULL, 0, format, ap2);
    va_end(ap2);
    char * str = malloc(len + 1);
    if (!str) return NULL;

    vsnprintf(str, len + 1, format, ap);
    return str;
}

char * bsprintf(const char * format, ...)
{
    va_list ap;
    va_start(ap, format);
    char * str = vbsprintf(format, ap);
    va_end(ap);
    return str;
}

if your system supports vsnprintf(NULL, 0, in order to determine the needed length.

7 Comments

it should be sprintf(path, GPIO_PATH_VALUE, 4);, its sprintf(char *, char *,...)
@SIGSEGV Of course. I was sure I had changed it. I'm getting old... Thank you for pointing out!
Why +5? Why malloc() and realloc(), and not only one malloc()?
To be generic here the necessary length would be strlen(GPIO_PATH_VALUE) - strlen("%d") + log10(INT_MAX) + 1 + 1);
@alk malloc() in oder to reserve definitely enough space, and realloc() to limit to the actually needed length. Your expression would work as well, but if someone changes the string to a more complicated one, it is not so easy any longer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.