输入字符串由空终止字符组成
Input string consists of null terminating chars
我正在使用 NanoPB 将编码数据(unsigned char
的数组)从服务器发送到客户端。我将每个字节映射为单个 char
,将它们连接起来,然后通过网络作为整个字符串发送。在客户端,我有一个串行接口,可以用 getc
或 gets
读取服务器的响应。问题是缓冲区可能有 null
-终止 char
s 并且 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] = '[=11=]';
}
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
不打印?
"Why readChars
print all the buffer but strInput
not?"
readChars()
函数在函数中实际打印所有读取的字符,一次一个:
while (c != EOF)
{
printf("%c", c);
c = fgetc(fp);
}
但是,strInput()
函数使用 %s
转换说明符将 buffer[]
的内容打印为字符串:
strInput(fp, buffer, sizeof(buffer));
printf("Reading with strInput (WRONG): %s\r\n", buffer);
这次遇到嵌入的 [=19=]
字符时打印停止,因为 %s
就是这样做的。
注意 readChars()
函数中的 c
应该是 int
,而不是 char
。 fgetc()
函数 returns 一个 int
值,并且 EOF
可能无法在 char
.
中表示
如果要查看嵌入的空字节,请一次打印一个来自 buffer[]
的字符:
#include <stdio.h>
int main(void)
{
FILE *fp = fopen("mybuffer.txt", "r"); // should check for open failure
char buffer[100] = { '[=12=]' }; // 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] == '[=12=]') {
putchar('*'); // some character not expected in input
}
else {
putchar(buffer[i]);
}
}
putchar('\n');
return 0;
}
我正在使用 NanoPB 将编码数据(unsigned char
的数组)从服务器发送到客户端。我将每个字节映射为单个 char
,将它们连接起来,然后通过网络作为整个字符串发送。在客户端,我有一个串行接口,可以用 getc
或 gets
读取服务器的响应。问题是缓冲区可能有 null
-终止 char
s 并且 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] = '[=11=]';
}
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
不打印?
"Why readChars
print all the buffer but strInput
not?"
readChars()
函数在函数中实际打印所有读取的字符,一次一个:
while (c != EOF)
{
printf("%c", c);
c = fgetc(fp);
}
但是,strInput()
函数使用 %s
转换说明符将 buffer[]
的内容打印为字符串:
strInput(fp, buffer, sizeof(buffer));
printf("Reading with strInput (WRONG): %s\r\n", buffer);
这次遇到嵌入的 [=19=]
字符时打印停止,因为 %s
就是这样做的。
注意 readChars()
函数中的 c
应该是 int
,而不是 char
。 fgetc()
函数 returns 一个 int
值,并且 EOF
可能无法在 char
.
如果要查看嵌入的空字节,请一次打印一个来自 buffer[]
的字符:
#include <stdio.h>
int main(void)
{
FILE *fp = fopen("mybuffer.txt", "r"); // should check for open failure
char buffer[100] = { '[=12=]' }; // 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] == '[=12=]') {
putchar('*'); // some character not expected in input
}
else {
putchar(buffer[i]);
}
}
putchar('\n');
return 0;
}