I'm using NanoPB to send an encoded data (array of unsigned char
) from a server to a client. I'm mapping each byte as a single char
, concatenate them, and next, send as a whole string through a network. In the client side, I have a serial interface that can read the server's response with getc
or gets
. Problem is the buffer might have null
-terminating char
s and gets
would fail. For example, suppose buffer contains something like this:
unsigned char buffer[] = {72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0, 24, 1, 32, 1, 40, 0};
For simplicity, I wrote the buffer to a file and trying to read it back and reconstruct it (with help of 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;
}
And here is the output:
Reading with strInput (WRONG): Hello world
Reading char by char: Hello world (
How can I reconstruct the buffer from that file?
Why readChars
print all the buffer but strInput
not?
"Why readChars
print all the buffer but strInput
not?"
The readChars()
function actually prints all characters as they are read, one at a time, in the function:
while (c != EOF)
{
printf("%c", c);
c = fgetc(fp);
}
But, the strInput()
function prints the contents of buffer[]
as a string using the %s
conversion specifier:
strInput(fp, buffer, sizeof(buffer));
printf("Reading with strInput (WRONG): %s\r\n", buffer);
Printing stops when an embedded \0
character is encountered this time, because that is what %s
does.
Note that c
in the readChars()
function should be an int
, not a char
. The fgetc()
function returns an int
value, and EOF
may not be representable in a char
.
If you want to see the embedded null bytes, print the characters from buffer[]
one at a time:
#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;
}