WedX - журнал о программировании и компьютерных науках

Целочисленный массив с пузырьковой сортировкой C — проблема вывода

Новичок Здесь.

Для моего класса программирования C мне нужно использовать пузырьковую сортировку для сортировки списка, прочитанного из входного файла .txt. Каждая строка в файле .txt содержит год, название и штаты, затронутые ураганом [год] [имя] [штаты].

Ex:

1999 Floyd NC
2003 Isabel NC, VA
2004 Charley FL, SC, NC
2004 Frances FL
...etc.

Программа должна отсортировать список по годам, сохраняя при этом правильность всех строк данных (сохраняйте относительные элементы массива вместе). Моя пузырьковая сортировка целочисленного массива работает нормально, за исключением одной проблемы: одна строка данных находится в стороне от списка. Вот пример вывода этой проблемы:

    1960    Donna    FL, NC
    1969    Camille  MS     1972    Agnes    FL
    1983    Alicia   TX
    2004    Charley  FL, SC, NC

Строка 1972 Agnes FL почти правильная, но по какой-то причине печатается сбоку, а не прямо под предыдущей строкой.

Код:

#include <stdio.h>
#include <string.h>

#define MAX_HURCS 30

int main() {
    FILE *hurricaneData;
    int year[MAX_HURCS];
    char name[MAX_HURCS][50];
    char states[MAX_HURCS][50];
    int i = 0, j;
    int count = 0;
    int sort;
    int tempYear;
    char tempName[50];
    char tempStates[50];

    if ((hurricaneData = fopen("hurricanes2.txt", "r")) == NULL) {
        printf("Error: Could not open file");
    }

    while ((fscanf(hurricaneData, "%d %s", &year[i], &name[i]) != EOF)
        && (fgets(states[i], 50, hurricaneData) != NULL)) {
        i++;
        count++;
    }

    for (i = 0; i < count - 1; i++) {
        for (j = 0; j < count - 1 - i; j++) {
            if (year[j] > year[j + 1]) {
                tempYear = year[j];
                year[j] = year[j+1];
                year[j+1] = tempYear;

                strcpy(tempName, name[j]);
                strcpy(name[j], name[j+1]);
                strcpy(name[j+1], tempName);

                strcpy(tempStates, states[j]);
                strcpy(states[j], states[j+1]);
                strcpy(states[j+1], tempStates);
            }
        }
    }
    for (i = 0; i < count; i++) {
        printf(" \t%d\t%s\t%s ", year[i], name[i], states[i]);
    }
    return 0;
}

Я также пробовал это для алгоритма сортировки, но столкнулся с той же проблемой:

for (i = 0; i < count; i++) {
    for (j = 0; j < count; j++) {
        if (year[j] > year[i]) {
            tempYear = year[i];
            year[i] = year[j];
            year[j] = tempYear;

            strcpy(tempName, name[i]);
            strcpy(name[i], name[j]);
            strcpy(name[j], tempName);

            strcpy(tempStates, states[i]);
            strcpy(states[i], states[j]);
            strcpy(states[j], tempStates);
        }
    }
}

  • Попробуйте ввести \n вручную в printf printf(\t%d\t%s\t%s\n, year[i], name[i], States[i]); 04.03.2019
  • Интересный. Когда я это делаю, выходной список распечатывается по порядку с этой строкой данных под другой, просто без пробела новой строки. Так что это технически правильно, но я считаю, что проблема с самым последним шагом в этом роде все еще существует. 04.03.2019
  • Это??, я думаю, ошибка в том, что ваша последняя строка в вашем файле не имеет символа конца строки, поэтому она читается до конца файла, и когда она печатает ту же строку, она не переходит к следующей строке, поэтому либо перейдите к последней строку в вашем текстовом файле и поместите endl в последнюю строку или напечатайте endl вручную для каждой строки, и ваш предыдущий комментарий я не вижу нового вывода 04.03.2019
  • Функция @TomKarzes fgets в любом случае будет считывать новую строку из текстового файла, поэтому нет смысла давать дополнительную новую строку после каждой строки, проблема в том, что последняя строка в текстовом файле не имеет новой строки. 04.03.2019
  • @ Анил, да, я понял это, когда посмотрел повнимательнее. Просто кажется странным переносить символы новой строки при сортировке. Обычно они удаляются при чтении записей, поскольку они не являются частью данных, а затем вставляются при выводе результата. Это правильный способ исправить это. 04.03.2019
  • Я использовал здесь fgets из-за разной длины и разделителей в массиве затронутых состояний. Я считаю, что fscanf не сможет правильно прочитать эту часть. Кроме того, сработало добавление конечной строки к документу. 04.03.2019
  • Вы не правильно читаете данные. Вы не должны использовать символы новой строки вместе со строками состояния. Они не являются частью данных. Что, если вы хотите напечатать что-то еще после состояний? Вы не могли бы, потому что у них есть символы новой строки. Если вы разбираете строки на поля, вы должны сделать это правильно, удалив символы новой строки. Тогда бы у вас не было таких ошибок. 04.03.2019
  • Ладно, теперь я понимаю, что ты имеешь в виду, Том. Благодарю вас! 04.03.2019
  • Думайте о новых строках как о разделителях записей, а не как о части данных. 04.03.2019

Ответы:


1

Я думаю, что ошибка заключается в том, что ваша последняя строка в вашем файле не имеет символа конца строки, поэтому она читается до конца файла, и когда она печатает ту же строку, она не переходит на следующую строку, поэтому либо перейдите к последней строке в вашем тексте файл и поставьте конец в последней строке или напечатайте конец вручную для каждой строки. Другим или более общим способом было бы удалить новую строку из вашего ввода, что можно сделать так, читая текст, сделайте это

int len = strlen(states[i]);
if(len>0 && states[i][len-1] == '\n')
{
    states[i][len-1] = '\0';
}

это удалит все новые строки, а затем вы сможете распечатать их вручную в printf

04.03.2019
  • Это правильно, я понимаю. Большое спасибо за вашу помощь в этом @Anil. 04.03.2019
  • Также необходимо проверить, что длина не равна нулю. Приведенный выше код небезопасен, если он встречает пустую строку без новой строки. В этом случае он будет индексировать начало строки, возможно, даже изменяя содержимое. 04.03.2019
  • Похоже, вы исправили это. Надеюсь, ОП заметит исправление. 04.03.2019
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]