对字符串中的字符进行排序的C程序
我在CI中写过这样的程序,它每行按行读取一个文件(每行只有一个字),对字母进行排序,然后在每个字符中显示排序字和原始字线。对字符串中的字符进行排序的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
我有两个问题:
- 输出文件在开始处有一堆换行符(即。abou t 5-7实际文字开始前的空白行)
- 为什么在最后打印'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'
值将始终是假的。这意味着,该代码不会做任何事
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 :)我只是在这里用它来说明这一点)
我发现一个小贴士是绘制我的数组,变量等在一张纸上,然后追踪我的代码(ag ain,纸上)来调试它的工作原理。
不行(因为它是一个数组)总是以空终止?在这种情况下,为什么line [i]!='\ 0'总是错误的? – xbonez 2010-10-14 02:45:26
'fgets'将空终止它写入的任何缓冲区。正因为如此,'line [i] =='\ 0''将成立。换个角度考虑一下:for循环只在'line [i]!='\ 0''时退出。然后你立即再次做同样的检查。当然你会得到同样的答案。 – 2010-10-14 02:49:15
但要回答*确切的*事情你问:“不行(因为它是一个数组)总是以空终止?”。不,数组可以有任何值。他们绝不会保证以null结尾,除非您手动执行该操作,或者您调用的函数可以保证执行该操作。 'fgets'做出了保证,但'word [i] = line [i];'没有。你必须自己终止'word'(只需在for循环后加':word [i] ='\ 0';')。 – 2010-10-14 02:51:59
你允许使用'string.h'函数吗?因为使用'strlen'和'strcpy'会更简单。目前,在复制之后,你并不是NUL-teriminating'word'。 – 2010-10-14 02:18:36
我想我可以使用 – xbonez 2010-10-14 02:35:34
这个作业吗?你可能想标记它。如果是这样,可惜你只限于C,它会成为其他几种语言的单行语言。 – Daenyth 2010-10-14 02:41:20