Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a complex string?

Tags:

c

string

printf

I have a bunch of printf()s that correctly print a quite complex string that I have to build.

The problem is that I need to store that string in a variable (the result of all those printf()s together for sending them via a socket. I'm quite sure I need them to be sent at once - but I'll let a small window open if you want to convince me that's not true.

What's the best way to achieve that?

The string length is REALLY variable. I've heard of sprintf() and realloc(), and even asprintf(), but I can't just see how to mix all these together.

Here's my current code:

void mostrarVariable(char *variable, void *valor) {
    printf("%s=%d\n", variable, *(int *)valor);
}

void mostrarEntradaStack(t_registro_stack *entradaStack) {
    printf("%d,%s\n", entradaStack->retorno, entradaStack->nombre_funcion);
}

void suspender(t_pcb *pcb) {
    char *mensaje = NULL;
    mensaje = strdup("1Proceso suspendido...");
    // FIXME: guardar los printf en una variable y enviarlo por la red

    printf("----------------\n\n");
    printf("ID=%d\n", pcb->id_proceso);
    printf("PC=%d\n", pcb->program_counter);
    printf("\n-- Estructura de codigo --\n");

    int indice = 0;

    // believe me: this iterates a char** printf-ing each line
    while(pcb->codigo[indice] != NULL) {
        printf("%s\n", pcb->codigo[indice++]);
    }

    printf("----------------\n");
    printf("\n-- Estructuras de datos --\n");

    // believe me: this calls mostrarVariable() for each entry in the pcb->datos dictionary
    dictionary_iterator(pcb->datos, mostrarVariable);

    printf("----------------\n\n");
    printf("-- Estructura de Stack --\n");

    // believe me: this calls mostrarEntradaStack() for each element in the stack without modifying it
    pila_hacer(pcb->stack, mostrarEntradaStack);

    printf("\n----------------\n");

    // believe me: this sends "mensaje" via a socket ("pcb->id_proceso"), and it handles the partial send()s and all of that
   // it has to be on one socket_send() to correctly send the message length to the other endpoint - the protocol pretty works
    socket_send(pcb->id_proceso, mensaje, strlen(mensaje) + 1);
}

Trust me, code currently works, but as mensaje just has the value "1Proceso suspendido...", data is printed locally instead of being sent to the remote.

Sample output:

----------------

ID=4
PC=6

-- Estructura de codigo --
#!/home/desert69/workspaces/operativos/no-quiero/procer/pi/build/pi
# Comentario
variables a,b,c,d,e
comienzo_programa
a=1
b=2;3
c=a+b
d=c-3
f1()
f2()
e=a+c;2
imprimir a
imprimir b
imprimir c
imprimir d
imprimir e
fin_programa
comienzo_funcion f1
a=3
f3()
b=4
fin_funcion f1
comienzo_funcion f2
a=a+1
fin_funcion f2
comienzo_funcion f3
c=d
fin_funcion f3
----------------

-- Estructuras de datos --
c=159769736
d=159769776
a=159769600
b=159769696
e=159769816
----------------

-- Estructura de Stack --

----------------

Sorry for the code in Spanish, but I wanted to be sure it's the exact same thing I'm running. Maybe later (if I can) I'll try to translate it, but I'm not sure. Even tough, the important thing is to replace every printf() to something for appending those outputs to mensaje.

Feel free to comment if you need any further info.

Thanks. Really :)

like image 899
mgarciaisaia Avatar asked Dec 18 '25 01:12

mgarciaisaia


1 Answers

The easiest way to do this is to concatenate a bunch of sprintf statements. Ignoring error conditions, the statement returns the number of characters written. So you can basically do this:

char *bufptr = buffer;
bufptr += sprintf( bufptr, "ID=%d\n", pcb->id_proceso );
bufptr += sprintf( bufptr, "PC=%d\n", pcb->program_counter );

etc

Then buffer contains the string built from successive calls to sprintf. Obviously you need to ensure the buffer is large enough. You also should handle errors if you anticipate any.

In addition, you get the final length of the string using bufptr - buffer, which is useful to know if you're sending this through a socket.

like image 136
paddy Avatar answered Dec 19 '25 20:12

paddy