我尝试使用read()从文件中获取一些字符,仅用于学习此API。我创建了一个名为" file"在同一目录中,它是内容:
1:2:ab:cd:ef
以下是代码:
#include <stdio.h>
#include <error.h>
int read_indent(int sockfd){
int sport, cport;
char user[3], rtype[3], addinfo[3];
char buffer[4+4+3+3+3+1];
if(read(sockfd, buffer, sizeof(buffer)) <= 0) {
perror("read: %m");
return -1;
}
buffer[sizeof(buffer)-1] = '\0';
sscanf(buffer, "%d:%d:%s:%s:%s", &sport, &cport, rtype, user, addinfo);
printf("%d:%d:%s:%s:%s", sport, cport, rtype, user, addinfo);
return 0;
}
int main(){
FILE *file_pt = fopen("file", "r");
if(file_pt == NULL) { printf("fopen error\n"); return -1;}
char buf[128];
int a = read_indent(fileno(file_pt));
fclose(file_pt);
return 0;
}
我的printf给我回复
1:2:ab:cd:ef::xPvx
其中x
是我无法识别的垃圾字符。这是什么原因? int
在我的系统中是4个字节。
答案 0 :(得分:1)
一个问题是您没有为%s
参数指定宽度。这意味着它匹配到第一个空格字符。字符串中没有空格字符,因此第一个%s
匹配到最后,只留下字符串后面的垃圾数据来填充其他变量。
试试这个:
sscanf(buffer, "%d:%d:%2s:%2s:%2s", &sport, &cport, rtype, user, addinfo);
另一个问题是你没有正确地终止你的缓冲区,read
返回读取的字符数 - 之后添加一个空格。
答案 1 :(得分:1)
char buffer[4+4+3+3+3+1];
缓冲区大于您打算阅读的内容并且没问题,但是:
buffer[sizeof(buffer)-1] = '\0';
这是错误的,在size+1
处添加 \ 0 ,其中size是您使用read()
获得的实际读取字节数。
请参阅here:
如果文件中剩余的字节数小于nbyte,如果read()请求被信号中断,或者文件是管道或FIFO或特殊文件,则返回的值可能小于nbyte可立即读取的字节数少于nbyte。
答案 2 :(得分:0)
char buffer[4+4+3+3+3+1];
if(read(sockfd, buffer, sizeof(buffer)) <= 0) {
//....
}
buffer[sizeof(buffer)-1] = '\0';
读取后,read函数不会向缓冲区添加\0
。但是你只读了12个字节,缓冲区大小为18.所以你的缓冲区中仍然有5个字节的垃圾。这会添加到您阅读的最后一个字符串中。