开发者

C program to sort characters in a string

I have this program in C I wrote that reads a file line by line (each line has just one word), sorts the alphabets, and then displays the sorted word and the original word in each line.

#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++)
开发者_如何学JAVA      {
        if (line[j] > line[i])
        {
          char temp;
          temp = line[j];
          line[j] = line[i];
          line[i]=temp;
        }
      }
    }
    printf("%s %s",line,word);

  }
  return 0;
}

I'm compiling and running it using the following bash commands.

gcc -o sign sign.c
./sign < sample_file | sort > output

The original file (sample_file) looks like this:

computer
test
file
stack
overflow

The output file is this:

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

I'm having two issues:

  1. The output file has a bunch of newline characters at the beginning (ie. about 5-7 blank lines before the actual text begins)
  2. Why does it print 'ter' twice at the end?

PS - I know these are very elementary questions, but I only just started working with C / bash for a class and I'm not sure where I am going wrong.


Problem 1

After this code, the variable line contains a line of text, including the newline character from the end of the string

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

This is why you are getting the "extra" newlines. The ASCII value for newline is less than the ASCII value for 'A'. That is why the newlines end up at the beginning of each string, once you've sorted the characters. E.g. "computer\n" becomes "\ncemoprtu".

To solve this, you can strip the newlines off the end of your strings, after the for-loop

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 */

This happens to solve problem 2, as well, but please read on, to see what was wrong.

Problem 2

After the loop

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

The string word will not be null-terminated (except by blind luck, since it is ready random uninitialized memory). This is why you get the "ter", because that is part of the data you left behind when you copied the word "computer" to word.

Problem 3

After the loop

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

The value of line[i] != '\0' will always be false. This means that this code will do nothing

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

It might make the problem more obvious if I replace the for-loop and the while-loop with basically identical code, using 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;
}

(btw, most professional programmers will do anything from laugh to yell at you if you mention using goto :) I only am using it here to illustrate the point)

A tip I find handy is to draw out my arrays, variables etc on a piece of paper, then trace through each line of my code (again, on paper) to debug how it works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜