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