Как правильно работать со строками в C? - PullRequest
2 голосов
/ 09 февраля 2011

Подобные Java, Python и другие погубили меня.Я пытаюсь автоматизировать FTP-клиент, отвечая на серверные коды:

Например:

// I know this is ugly, please bear with me

char username[25];
strcat(username, USER); //"USER "
strcat(username, usr); // "foo"
strcat(username, "\n"); // = "USER foo\n"

char password[25];
strcat(password, PASS); //"PASS "
strcat(password, pswd); //"bar"
strcat(password, "\n"); // = "PASS bar\n"


//read/write loop

while (1) { 

    char* responsePtr;
    serverCode = readSocket(sockfd, mybuffer);

    if (serverCode == 221) 
                    break;

    if (serverCode == 220)
        responsePtr = &username;

    if (serverCode == 331)
        responsePtr = &password;

    writeSocket(sockfd, responsePtr);

}

Когда я пытаюсь это сделать, это работает для ПОЛЬЗОВАТЕЛЯ, но я получаю искаженный текст дляПРОЙДИТЕ:

C->S: USER anonymous
S->C: 331 Please specify the password.
C->S: (??_?PASS random

Может ли кто-нибудь, кто умнее и опытнее меня, подскажет мне C-струнные указатели?Очевидно, это не работает для меня.

Ответы [ 4 ]

12 голосов
/ 09 февраля 2011

Вам нужно инициализировать ваши строки, прежде чем объединять их.Массивы не инициализируются по умолчанию.

char username[25] = "";
char password[25] = "";

Для чего бы вы ни стояли, вы можете использовать sprintf, чтобы упростить создание строк:

sprintf(username, "USER %s\n", usr);
sprintf(password, "PASS %s\n", pswd);

Надеемся, вы также понимаете, что с помощью fixedРазмер буфера является рецептом для ошибок переполнения буфера.В целях безопасности вы должны быть осторожны от них.Это раздражает, но это C для вас:

if (snprintf(username, 25, "USER %s\n", usr)  >= 25 ||
    snprintf(password, 25, "PASS %s\n", pswd) >= 25)
{
    fprintf(stderr, "buffer overflow\n");
    exit(EXIT_FAILURE);
}
1 голос
/ 09 февраля 2011

Несколько правил, которые помогают.

  • Не забудьте инициализировать и завершить нулем ваши строки.
  • Используйте функции библиотеки.
  • Проверьте длину строки и / или используйте n (ограниченный размер) функций при работе с внешними данными.
  • Не забывайте терминатор при определении размера буферов.
0 голосов
/ 09 февраля 2011

Вы не должны размещать неинициализированный массив.Попробуйте:

char *password[25] = "";
password = strcat(PASS);

для первого.

Кроме того, вместо strcat() вы должны использовать strncat(), чтобы избежать переполнения.


Я думаюэто проще сделать:

int len = snprintf(password, 25, "%s %s\n", PASS, pswd);
if (len > 25) {
    // oops! password is too long dude :-(
}

См. здесь несколько примеров .

0 голосов
/ 09 февраля 2011

Попробуйте добавить «\ n \ 0» вместо просто «\ n» к массивам имени пользователя и пароля.

...