C程序对字符串中的字符进行排序

我在CI编写的这个程序中逐行读取文件(每行只有一个单词),对字母进行排序,然后在每一行中显示已排序的单词和原始单词。

#include int main() { char line[128]; int i=0; int j; int length; while(fgets(line,sizeof line,stdin) != NULL) { char word[128]; for (i=0; line[i] != '\0'; i++) { word[i]=line[i]; } while (line[i] != '\0') i++; length=i; for (i=length-1; i >=0; i--) { for (j=0; j line[i]) { char temp; temp = line[j]; line[j] = line[i]; line[i]=temp; } } } printf("%s %s",line,word); } return 0; } 

我正在使用以下bash命令编译和运行它。

 gcc -o sign sign.c ./sign  output 

原始文件(sample_file)如下所示:

 computer test file stack overflow 

输出文件是这样的:

 ackst stack cemoprtu computer efil file efloorvw overflow er estt test ter ter 

我有两个问题:

  1. 输出文件在开头有一堆换行符(即在实际文本开始之前大约5-7个空白行)
  2. 为什么最后两次打印’ter’?

PS – 我知道这些都是非常基本的问题,但我只是开始使用C / bash上课,我不确定我哪里出错了。

问题1

在此代码之后,变量line包含一行文本,包括字符串末尾的换行符

 while(fgets(line,sizeof line,stdin) != NULL) { 

这就是你获得“额外”换行的原因。 换行的ASCII值小于’A’的ASCII值。 这就是为什么一旦你对字符进行排序,换行就会在每个字符串的开头结束。 例如“computer \ n”变成“\ ncemoprtu”。

要解决此问题,您可以在for循环之后删除字符串末尾的换行符

 if(i > 0 && word[i-1] == '\n') { word[i-1] = '\0'; line[i-1] = '\0'; --i; } 

 printf("%s %s\n",line,word); /* notice the addition of the newline at the end */ 

这也恰好解决了问题2,但请继续阅读,看看有什么问题。

问题2

循环之后

 for (i=0; line[i] != '\0'; i++) { /* */ } 

字符串word不会以空值终止(除了盲目的运气,因为它是随机的未初始化的内存)。 这就是你得到“ter”的原因,因为这是你将单词“computer”复制到word时留下的数据的一部分。

问题3

循环之后

 for (i=0; line[i] != '\0'; i++) { /* */ } 

line[i] != '\0'将始终为false。 这意味着此代码将不执行任何操作

 while (line[i] != '\0') i++; 

如果我用基本相同的代码替换for循环和while循环,使用goto可能会使问题更加明显:

 i=0; begin_for_loop: if(line[i] != '\0') { { word[i]=line[i]; } i++; goto begin_for_loop; } begin_while_loop: if(line[i] != '\0') { i++; goto begin_while_loop; } 

(顺便说一句,如果你提到使用goto,大多数专业程序员会做任何事情,从笑到大喊你:)我只是在这里使用它来说明这一点)

我发现一个方便的提示是在一张纸上绘制我的数组,变量等,然后跟踪我的代码的每一行(再次,在纸上)来调试它的工作原理。