Something equivalent to the sstream library from C++ to C

Asked

Viewed 255 times

0

I need something similar to the stringstream you have in the C++ connection for the C language, I need it a lot because I want to make querys in a database using C (C mysql Connector).

Since I had no idea what I had in the sstream library for C I thought of using strncat, but it didn’t come out as planned, note:

#include <string.h>
#include <stdio.h>

int main(){

    char username[25];
    char passwd[45];

    printf("Input your name ->");
    fgets(username, 25, stdin);

    printf("Input your password->");
    fgets(passwd, 45, stdin);

    char query[128]="select username, password from accounts where username='";
    char and[18]="' and password='";

    strncat(query, username, 25);
    strncat(query, and, 16);
    strncat(query, passwd, 45);
    strncat(query, "';\n", 4);

    printf("%s", query);

    return 0;

    //OBS: Código de exemplo
}

When I run the show:

gcc main.c
./a.out
Input your name ->linus
Input your password->123
select username, password from accounts where username='linus
' and password='123
';

Note that he skipped a line and gave some spaces and this in a query could generate error.

1 answer

1


The problem is that the fgets also reads the \n and stores in the buffer reading. You can resolve this by manually removing the \n that was the last caretere read:

fgets(username, 25, stdin);
size_t ultima_pos = strlen(username) - 1;
if (username[ultima_pos] == '\n'){
    username[ultima_pos] = '\0'; //terminar a string no local onde está o `\n`
}

In order not to have to repeat this logic for all readings, I suggest that the abstraction through a reading function:

void ler_string(char *destino, size_t tamanho){
    fgets(destino, tamanho, stdin);
    size_t ultima_pos = strlen(destino) - 1;
    if (destino[ultima_pos] == '\n'){
        destino[ultima_pos] = '\0';
    }
}

Calling her that:

ler_string(username, 25);

For what you’re trying to build becomes much simpler to interpolate the values you want within the string using sprintf, which avoids having to do multiple concatenations:

sprintf(query,"select username, password from accounts where username='%s' and password='%s'\n", username, passwd);

Put it all together your show would be like this:

#include <string.h>
#include <stdio.h>

void ler_string(char *destino, size_t tamanho){
    fgets(destino, tamanho, stdin);
    size_t ultima_pos = strlen(destino) - 1;
    if (destino[ultima_pos] == '\n'){
        destino[ultima_pos] = '\0';
    }
}

int main(){
    char username[25];
    char passwd[45];

    printf("Input your name ->");
    ler_string(username, 25);

    printf("Input your password->");
    ler_string(passwd, 45);

    char query[128];
    sprintf(query,"select username, password from accounts where username='%s' and password='%s'\n", username, passwd);
    printf("%s", query);

    return 0;
}

View your execution on Ideone

Note:

I recommend you to watch out for Mysql Injection attacks, which is something that is susceptible to this approach without controlling the input that the user gives in the program.

  • Wouldn’t it be better just in case, to check if the entrance was a whole line? If it is a truncated input (reached EOF, for example), I have the impression that the last character would not be \n

  • @Jeffersonquesado Yes indeed would be playing it safe. I also agree that it is better. I will edit

  • @Isac Exactly this information I needed. Thanks!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.