为什么要打印额外的垃圾字符?

时间:2015-03-14 16:22:45

标签: c string

我尝试使用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个字节。

3 个答案:

答案 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个字节的垃圾。这会添加到您阅读的最后一个字符串中。