Входная строка состоит из нулевых завершающих символов - PullRequest
0 голосов
/ 12 декабря 2018

Я использую NanoPB для отправки закодированных данных (массив unsigned char) с сервера на клиент.Я отображаю каждый байт как один char, объединяю их, а затем отправляю как целую строку через сеть.На стороне клиента у меня есть последовательный интерфейс, который может прочитать ответ сервера с помощью getc или gets.Проблема в том, что буфер может иметь null -определение char с, а gets завершится ошибкой.Например, предположим, что буфер содержит что-то вроде этого:

unsigned char buffer[] = {72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 24, 1, 32, 1, 40, 0};

Для простоты я записал буфер в файл и пытался прочитать его обратно и восстановить его (с помощью this ):

#include <stdio.h>

void strInput(FILE *fp, char str[], int nchars) {
    int i = 0;
    int ch;
    while ((ch = fgetc(fp)) != '\n' && ch != EOF) {
        if (i < nchars) {
            str[i++] = ch;
        }
    }
    str[i] = '\0';
}

void readChars(FILE *fp)
{
    char c = fgetc(fp);
    while (c != EOF)
    {
        printf("%c", c);
        c = fgetc(fp);
    }
}


int main() {
    FILE *fp;
    const char* filepath = "mybuffer.txt";
    char c;
    char buffer[100];

    fp = fopen(filepath, "r+");    
    strInput(fp, buffer, sizeof(buffer));
    printf("Reading with strInput (WRONG): %s\r\n", buffer);
    fclose(fp);

    fp = fopen(filepath, "r+");
    printf("Reading char by char: ");
    readChars(fp);
    printf("\r\n");
    fclose(fp);

    getchar();
    return 0;
}

А вот вывод:

Reading with strInput (WRONG): Hello world
Reading char by char: Hello world  (

Как я могу восстановить буфер из этого файла?Почему readChars печатает весь буфер, а strInput нет?

1 Ответ

0 голосов
/ 12 декабря 2018

«Почему readChars печатает весь буфер, но strInput нет?»

Функция readChars() фактически печатает все символы по мере их чтения, по одному, в функции:

while (c != EOF)
    {
        printf("%c", c);
        c = fgetc(fp);
    }

Но функция strInput() печатает содержимое buffer[] в виде строки, используя спецификатор преобразования %s:

strInput(fp, buffer, sizeof(buffer));
printf("Reading with strInput (WRONG): %s\r\n", buffer);

Печать останавливается, когда внедренный символ \0встречается на этот раз, потому что это то, что %s делает.

Обратите внимание, что c в функции readChars() должно быть int, а не char.Функция fgetc() возвращает значение int, и EOF может не отображаться в char.

Если вы хотите увидеть встроенные нулевые байты, выведите символы из buffer[] одинза один раз:

#include <stdio.h>

int main(void)
{
    FILE *fp = fopen("mybuffer.txt", "r");  // should check for open failure

    char buffer[100] = { '\0' };  // zero to avoid UB when printing all chars
    fgets(buffer, sizeof buffer, fp);
//  could just as well use:
//  strInput(fp, buffer, sizeof(buffer));

    for (size_t i = 0; i < sizeof buffer; i++) {
        if (buffer[i] == '\0') {
            putchar('*');        // some character not expected in input
        }
        else {
            putchar(buffer[i]);
        }
    }
    putchar('\n');

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...