user-0 提问: K&R 的书中 通过编写 UNIX 程序 sort 的一个简化版本说明这一点。 该程序按字母顺序对由文本行组成的集合进行排 序。请问这个程序要如何结束输入？

回复:
user: user-0
content: 引用 3 楼 zhao4zhong1 的回复:Linux：Ctrl+D Windows：Enter、Ctrl+Z、Enter  Ctrl+D 已经试过了。

user: user-1
content: Linux：Ctrl+D Windows：Enter、Ctrl+Z、Enter

user: user-0
content: 引用 6 楼 zhao4zhong1 的回复:不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。   恩，感谢指点。

user: user-0
content: 由于在调试的程序中又发现了一些问题，所以把最后的代码贴上来  /* 	date:9-2-2014 	author:doodlesomething 	version:1.0  	sort strings as linux tool  	how: 	1.read lines; 	2.sort lines; 	3.write lines; */  #include <stdio.h> #include <string.h>  #define MAXLINES 1000	//define the maxsize of input lines #define MAXBUFPSIZE 50000 //define the maxsize of bufp  #define MAXLEN 1000 //the maxsize of evey line  char *lineptr[MAXLINES];  //to store the pointers of lines  int readlines(char *lineptr[],int lim); void writelines(char *lineptr[],int nlines);  void qsort(char *lineptr[],int left,int right);   //main function  int main() { 	int nlines; 	//the number of all input lines 	//when the nlines bigger than 1 we sort the lines 	if( (nlines = readlines(lineptr,MAXLINES) ) >1) { 		qsort(lineptr,0,nlines-1); 		writelines(lineptr,nlines); 		return 0; 	} 	else { 		printf("the input line is too big!Sorry we can not handle it\n"); 		return 1; 	} 	return 0; }  	//read line string 	int readlines(char *lineptr[],int lim)	{ 		int len,inlines; 		char *p; 		char line[MAXLEN]; 		int getLine(char *line,int lim); 		char *alloc(int n); 	 		inlines = 0; 		 		while( (len = getLine(line,MAXLEN)) > 0 ) { 			if( inlines > lim ||  ( p = alloc(len) ) == NULL )  				return -1; 			else { 				/* 				the end of input line is '\n',and we should store it 				as a string so we can should add a flag '\0' end of a string array 				*/ 				line[len-1]='\0';   				strcpy(p,line); 				lineptr[inlines++]=p; 			} 		}  		return inlines; 	}   	//quick sort the lines -- key code 	void qsort(char *lineptr[],int left,int right) { 		int last,i; 		void swap(char *v[],int i,int j); 		//if the lines fewer than two 		if(left >= right) 			return; 		 		swap(lineptr,left,(left+right)/2);  		last = left;  		for(i=left+1;i <= right;i++) { 			if( strcmp(lineptr[i],lineptr[left]) <0 ) 				swap(lineptr,++last,i); 		} 		 		swap(lineptr,left,last); 		qsort(lineptr,left,last-1); 		qsort(lineptr,last+1,right); 	}  	//swap pointer 	void swap(char *v[],int i,int j) { 		char *tmp; 		tmp=v[i]; 		v[i]=v[j]; 		v[j]=tmp; 	}  	//write line string 	void writelines(char *lineptr[],int nlines) { 		printf("\nThe result is :\n\n"); 		while(--nlines>0) { 			printf("%s\n",*lineptr++); 		} 	}  	//get the single line 	int getLine(char *line,int lim) { 		int c; 		char *tmp;  		tmp = line; 		 		while(--lim > 0 && (c = getchar()) != EOF && c != '\n') 			*tmp++=c;  		if(c == '\n') 			*tmp++= c;  		*tmp= '\0';  		//return the length of line 		return (int) (tmp-line); 	} 	 	//buf 	static char buf[MAXBUFPSIZE]; 	static char *bufp = buf;  	//ask for buf 	char *alloc(int n) { 		if(n > 0 && (buf + MAXBUFPSIZE - bufp) >= n) { 			bufp = bufp + n; 			return (bufp - n); 		} 		else  			return 0; 	}  	//free buf 	void afree(char *p) { 		if( p >= buf && p < (buf + MAXBUFPSIZE) ) 			bufp = p; 	}

user: user-0
content: 引用 5 楼 cyd54454 的回复:*++tmp= '\0';原因我想是在这，你就算按了ctrl+d，结果你还是把tmp++了，那么你返回的长度是tmp - line = 1，函数返回之后的while循环中len = 1 > 0.当然不会结束了  一语惊醒啊，程序应该改为：               if(c == '\n')                        *tmp++= c;                   *tmp= '\0';  这样当另起一行时马上输入Ctrl+D时，tmp并没有自加，返回值就为0了。 感谢！！！（自己没有认真想问题可能会出现在哪就伸手党了）

user: user-1
content: 不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

user: user-2
content: *++tmp= '\0';原因我想是在这，你就算按了ctrl+d，结果你还是把tmp++了，那么你返回的长度是tmp - line = 1，函数返回之后的while循环中len = 1 > 0.当然不会结束了

user: user-0
content: 引用 1 楼 zmlovelx 的回复:可以试试回车之后加ctrl+D  我之前就测试过回车ctrl+d，不管用。

user: user-3
content: 可以试试回车之后加ctrl+D