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

标签 c

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

#include<stdio.h>

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<i; j++)
      {
        if (line[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 < sample_file | sort > 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 值。这就是为什么在对字符进行排序后,换行符会出现在每个字符串的开头。例如。 “计算机\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 不会以 null 结尾(除非运气不好,因为它已准备好随机未初始化的内存)。这就是您得到“ter”的原因,因为当您将单词“computer”复制到 word 时,它是您留下的数据的一部分。

问题 3

循环之后

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

line[i] != '\0' 的值将始终为 false。这意味着这段代码什么都不做

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

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

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,大多数专业程序员都会对你大笑大吼:)我在这里只是用它来说明这一点)

我发现一个有用的技巧是在一张纸上画出我的数组、变量等,然后跟踪我的代码的每一行(同样,在纸上)以调试它是如何工作的。

关于C程序对字符串中的字符进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3929547/

相关文章:

使用 ptrace() 取消系统调用

c - OS X CommonCrypto 是否为 OpenSSL EVP_* 调用提供了兼容模式(就像 OpenSSL MD5 函数一样)?

c - (初级程序员)需要帮助 : Linked Lists in C

c - 无法识别空格 - 其他 ASCII 字符是

c - 如何优化阀门仿真逻辑?

c - 如何在 C 中执行命令并读取其输出

c - 乘以 0.5 而不是除以 2

c - 什么是 (void (**) ()) 以及如何对它进行类型定义?

c - 将值从 void 指针分配给非 void 指针

C 编程 : Using struct Accessing an array within an array during a for loop