C 不幸的是,我的程序不想用空终止符替换换行符

C 不幸的是,我的程序不想用空终止符替换换行符,c,string,char,string-comparison,C,String,Char,String Comparison,我目前正在使用C语言中的套接字,似乎我们无法将输出正确地放入缓冲区。它的工作原理是,客户机将字符串分块发送到服务器。服务器等待,直到在字符串中找到换行符。一旦有了字符串,它就用空终止符替换换行符,然后打印缓冲区。程序将额外数据移动到缓冲区的前端,并重复该过程 不幸的是,我的程序不想用空终止符替换换行符。 所有测试代码的尝试都以字符串以片段形式输出结束 #include <stdio.h> #include <string.h> #include <stdlib.h&

我目前正在使用C语言中的套接字,似乎我们无法将输出正确地放入缓冲区。它的工作原理是,客户机将字符串分块发送到服务器。服务器等待,直到在字符串中找到换行符。一旦有了字符串,它就用空终止符替换换行符,然后打印缓冲区。程序将额外数据移动到缓冲区的前端,并重复该过程

不幸的是,我的程序不想用空终止符替换换行符。 所有测试代码的尝试都以字符串以片段形式输出结束

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>


#ifndef PORT
  #define PORT 30000
#endif


int setup(void) {
  int on = 1, status;
  struct sockaddr_in self;
  int listenfd;
  if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }

  // Make sure we can reuse the port immediately after the
  // server terminates.
  status = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
                      (const char *) &on, sizeof(on));
  if(status == -1) {
    perror("setsockopt -- REUSEADDR");
  }

  self.sin_family = AF_INET;
  self.sin_addr.s_addr = INADDR_ANY;
  self.sin_port = htons(PORT);
  memset(&self.sin_zero, 0, sizeof(self.sin_zero));  // Initialize sin_zero to 0

  printf("Listening on %d\n", PORT);

  if (bind(listenfd, (struct sockaddr *)&self, sizeof(self)) == -1) {
    perror("bind"); // probably means port is in use
    exit(1);
  }

  if (listen(listenfd, 5) == -1) {
    perror("listen");
    exit(1);
  }
  return listenfd;
}


/*
 * Search the first inbuf characters of buf for a network newline ("\r\n").
 * Return the location of the '\r' if the network newline is found,
 * or -1 otherwise.
 * Definitely do not use strchr or any other string function in here. (Why not?)
 */
int find_network_newline(const char *buf, int inbuf) {
  int i = 0;
  int found = 0;
  int location = 0;
  while(i < inbuf && found == 0){
    if(buf[i] == "\r"){
      location = i;
      found = 1;
    }
    i++;
  }
  if(found = 1){
    return location;
  }
  return -1; // return the location of '\r' if found
}


int main(void) {
  int listenfd;
  int fd, nbytes;
  char buf[30];
  int inbuf; // how many bytes currently in buffer?
  int room; // how much room left in buffer?
  char *after; // pointer to position after the (valid) data in buf
  int where; // location of network newline

  struct sockaddr_in peer;
  socklen_t socklen;

  listenfd = setup();
  while (1) {
    socklen = sizeof(peer);
    // Note that we're passing in valid pointers for the second and third
    // arguments to accept here, so we can actually store and use client
    // information.
    if ((fd = accept(listenfd, (struct sockaddr *)&peer, &socklen)) < 0) {
      perror("accept");

    } else {
      printf("New connection on port %d\n", ntohs(peer.sin_port));

      // Receive messages
      inbuf = 0;          // buffer is empty; has no bytes
      room = sizeof(buf); // room == capacity of the whole buffer
      after = buf;        // start writing at beginning of buf

      while ((nbytes = read(fd, after, room)) > 0) {
        // Step 2: update inbuf (how many bytes were just added?)
        inbuf = inbuf + nbytes;

        // Step 3: call find_network_newline, store result in variable "where"
        where = find_network_newline(buf, inbuf);

        if (where >= 0) { // OK. we have a full line

          // Step 4: output the full line, not including the "\r\n",
          // using print statement below.
          // Be sure to put a '\0' in the correct place first;
          // otherwise you'll get junk in the output.
          // (Replace the "\r\n" with appropriate characters so the
          // message prints correctly to stdout.)
          buf[where] = "\0";
          printf("Next message: %s", buf);
          // Note that we could have also used write to avoid having to
          // put the '\0' in the buffer. Try using write later!


          // Step 5: update inbuf and remove the full line from the buffer
          // There might be stuff after the line, so don't just do inbuf = 0

          // You want to move the stuff after the full line to the beginning
          // of the buffer.  A loop can do it, or you can use memmove.
          // memmove(destination, source, number_of_bytes)
      after += where;
      memmove(buf, after, 30);
      inbuf = strlen(buf);

        }
        // Step 6: update room and after, in preparation for the next read
    room = 30 - inbuf;
    after = buf;

      }
      close(fd);
    }
  }
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#ifndef端口
#定义端口30000
#恩迪夫
int设置(无效){
int on=1,状态;
self中的结构sockaddr_;
int-listenfd;
if((listenfd=socket(AF_INET,SOCK_STREAM,0))=-1){
佩罗(“插座”);
出口(1);
}
//确保我们可以在测试完成后立即重用该端口
//服务器终止。
状态=setsockopt(已列出、SOL_插槽、SO_REUSEADDR、,
(const char*)&on,sizeof(on));
如果(状态==-1){
perror(“setStockopt--REUSEADDR”);
}
self.sin_family=AF_INET;
self.sin\u addr.s\u addr=INADDR\u ANY;
self.sin_port=htons(port);
memset(&self.sin_zero,0,sizeof(self.sin_zero));//将sin_zero初始化为0
printf(“侦听%d\n”,端口);
if(bind(listenfd,(struct sockaddr*)&self,sizeof(self))=-1){
perror(“bind”);//可能表示端口正在使用中
出口(1);
}
如果(侦听(listenfd,5)=-1){
佩罗尔(“倾听”);
出口(1);
}
返回listenfd;
}
/*
*在buf的第一个inbuf字符中搜索网络换行符(“\r\n”)。
*如果找到网络换行符,则返回“\r”的位置,
*否则为-1。
*绝对不要在这里使用strchr或任何其他字符串函数。(为什么不呢?)
*/
int find_network_newline(常量字符*buf,int inbuf){
int i=0;
int=0;
int位置=0;
而(i0){
//步骤2:更新inbuf(刚刚添加了多少字节?)
inbuf=inbuf+n字节;
//步骤3:调用find_network_newline,将结果存储在变量“where”中
其中=查找网络新线(buf,inbuf);
如果(其中>=0){//好的。我们有一个完整的行
//步骤4:输出整行,不包括“\r\n”,
//使用下面的打印语句。
//请确保首先将“\0”放在正确的位置;
//否则,您将在输出中得到垃圾。
//(用适当的字符替换“\r\n”,以便
//消息正确打印到标准输出。)
buf[其中]=“\0”;
printf(“下一条消息:%s”,buf);
//注意,我们也可以使用write来避免
//将“\0”放入缓冲区。请稍后尝试使用“写入”!
//步骤5:更新inbuf并从缓冲区中删除整行
//行后面可能有东西,所以不要只做inbuf=0
//您想将整行之后的内容移到开头
//一个循环可以做到这一点,也可以使用memmove。
//memmove(目标、源、字节数)
+之后=其中;
memmove(buf,after,30);
inbuf=strlen(buf);
}
//第6步:更新房间和之后,为下次阅读做准备
房间=30-inbuf;
之后=buf;
}
关闭(fd);
}
}
返回0;
}

这是因为您正在将
buf[i]
与不带字符的字符串进行比较

if(buf[i] == "\r")
应该是

if(buf[i] == '\r')
buf[where] = '\0';

应该是

if(buf[i] == '\r')
buf[where] = '\0';

尝试使用“\0”而不是“\0”,我认为它应该会起作用。

你们男人“\'not'/”打开编译器警告并花时间学习如何调试自己的程序。你们不需要编写,也可以执行
printf(“下一条消息:%.*s”,其中,buf)
if(buf[i]=“\r”)
应生成编译器警告。启用所有警告以节省我们的所有时间。
buf[where]=“0”
错误,应该是
buf[where]='\0'