C программа для сортировки символов в строке - PullRequest
1 голос
/ 14 октября 2010

У меня есть программа на 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 Ответ

2 голосов
/ 14 октября 2010

Задача 1

После этого кода переменная line содержит строку текста, включая символ новой строки от конца строки

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

Вот почему вы получаете "лишние" переводы строк. Значение ASCII для новой строки меньше, чем значение ASCII для «A». Вот почему символы новой строки заканчиваются в начале каждой строки, как только вы отсортировали символы. Например. "компьютер \ 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 не будет оканчиваться нулем (кроме случаев слепой удачи, поскольку она готова к случайной неинициализированной памяти). Вот почему вы получаете «тер», потому что это часть данных, которые вы оставили, когда вы скопировали слово «компьютер» в 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 :) Я использую это здесь только для иллюстрации сути)

Совет, который я нахожу удобным, - это нарисовать мои массивы, переменные и т. Д. На листе бумаги, а затем проследить каждую строку моего кода (опять же на бумаге), чтобы отладить, как он работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...