Входная строка состоит из нулевых завершающих символов
Я использую NanoPB для отправки закодированных данных (массив unsigned char
) с сервера на клиента. Я отображаю каждый байт как отдельный char
соедините их, а затем отправьте через сеть как целую строку. На стороне клиента у меня есть последовательный интерфейс, который может прочитать ответ сервера с getc
или же gets
, Проблема в том, что буфер может иметь null
-terminating char
с и gets
потерпит неудачу Например, предположим, что буфер содержит что-то вроде этого:
unsigned char buffer[] = {72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 24, 1, 32, 1, 40, 0};
Для простоты я записал буфер в файл и попытался прочитать его обратно и восстановить его (с помощью этого):
#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 ответ
"Зачем 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;
}