The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Проблема новичка , !*! A6e3iana, 14-Янв-22, 10:51  [смотреть все]
Всем доброго времени суток. Изучаю программирование и решая задачу столкнулся с проблемой, нуждаюсь в объяснении что я делаю не так. Приступим:
Задача 12.7: Даны две фамилии. Определить, какая из них длиннее. (из задачника "1400 задач по программированию" от Златопольский Д.М.)
Для себя решил что входные данные поданы в виде одной строки.
Код решения компилируется без замечаний (gcc -Wall -g file.c -o file).
При запуске программы получаю бесконечный ввод данных.
Тестируя отдельно самолепную функцию GetString таких проблем не получаю и ввод заканчивается как и задумано при нажатии клавиши Enter. Добавление 1 следующей строчки кода и отладочной печати ведет к вышеназванной проблеме бесконечного ввода. Объясните что я делаю не так. Спасибо за внимание.
Вот код решения задачи:

#include <stdio.h>

int GetString(char *str, int strsize)
{
    char c;
    int i=0;

    while ((c=getchar())!='\n') {
        if (i<=strsize-1){
            str[i]=c;
            i++;
        }
    }
    str[i]='\0';
    return 0;
}

int GetWord (char *str, int number, char *word, int wordsize)
{
    int i=0, k=0;
    int countword=0;
    char prev=' ';

    while (str[i]!='\0') {
        if (prev==' ' && str[i]!=' ') {
            countword++;
        }
        if (countword==number && str[i]!=' ' && k<=wordsize-1) {
            word[k]=str[i];
            k++;
        }
        prev=str[i];
    }
    word[k]='\0';
    return  k;
}

int main () {
    enum {strsize=100, wordsize=20};
    char str[strsize];
    char surname1[wordsize];
    char surname2[wordsize];
    int lensurname1=0;
    int lensurname2=0;

    GetString(str, strsize);
    lensurname1=GetWord (str, 1, surname1, wordsize);
    lensurname2=GetWord (str, 2, surname2, wordsize);
    if (lensurname1 > lensurname2 ) {
        printf("%s is longer than %s!\n", surname1, surname2);
    }
    if (lensurname1 < lensurname2 ) {
        printf("%s is longer than %s!\n", surname2, surname1);
    }
    if (lensurname1 == lensurname2 ) {
        printf("Surnames are equal!\n");
    }
    return 0;
}

  • Проблема новичка , !*! Аноним, 17:02 , 14-Янв-22 (2)
    Проблема в незнании сей. На глаз сразу вижу что гетстринг не работает, дальше и смотреть не хочется.


  • Проблема новичка , !*! parad, 09:42 , 15-Янв-22 (3)
    >[оверквотинг удален]
    >         }
    >         if (countword==number && str[i]!='
    > ' && k<=wordsize-1) {
    >            
    > word[k]=str[i];
    >            
    > k++;
    >         }
    >         prev=str[i];
    >     }

    в этом цикле нету инкремента i.

  • Проблема новичка , !*! ACCA, 21:09 , 17-Янв-22 (5)
    Хороший пример, как НЕ НУЖНО писать программы. Сравни с этим:


    #include <stdio.h>

    int main(int argc, char* argv[]) {
        if (argc != 3) {
           puts("need 2 surnames\n");
           return 1;
        }
        int diff = strlen(argv[1]) - strlen(argv[2]);

        if (diff >0) {
           printf("%s longer than %s\n", argv[1], argv[2]);
           return 0;
        }
        if (diff <0) {
           printf("%s shorter than %s\n", argv[1], argv[2]);
           return 0;
        }

        printf("%s and %s are equal length\n", argv[1], argv[2]);
        return 0;
    }

    • Проблема новичка , !*! A6e3iana, 10:02 , 18-Янв-22 (6)
      > Хороший пример, как НЕ НУЖНО писать программы. Сравни с этим:

      Приветствую! Спасибо за комментарий! Очень важен для меня ибо поднимает актуальные вопросы.

      Первый: "Как выглядит промышленный код?" По задумке выношу реализацию в отдельные функции и в main оставляю только общую логику и организацию данных. На данном этапе на простых программах это избыточный код, но может быть такая привычка даст результаты в будущем?

      Второй: "Как правильно учиться?" Где то прочел: пока не знаешь как устроенны и работают простые библиотечные функции не используй их, а пиши свои реализации". ПОДЧЕРКНУ: совет для стадии обучения. Мне он понравился вот и леплю как могу.

      Из Примера подчеркнул:
      Проверку входный данных - полезно, ЗАПОМНЮ!
      Введение переменной хранящей разницу вместо постоянного сравнения и её имя "diff". ЗАПОМНЮ!
      Это вообще мрак придумывать имена для переменных на англ да ещё как можно короче.

      Что думаете о выше поставленных вопросах?


      • Проблема новичка , !*! Конч, 20:40 , 18-Янв-22 (9)
        >На данном этапе на простых программах это избыточный код, но может быть такая привычка даст результаты в будущем?

        Изменения в конкретной функции затрагивают её поведение. Если ты кладёшь весь код в одну функцию и в ней много кода, при изменении может много что сломаться. Ну и лично у меня есть правило не класть в одну функцию кода больше, чем помещается на экране, правда вот, на си я обычно не пишу, на си бы я лимит строк мог бы и увеличить, возможно.
        Просто если это читает другой человек, то для того, чтобы понять смысл функции, ему придётся мотать функцию туда-сюда. Если же она примерно умещается на экране (25-50 строк где-то - мой верхний лимит обычно), то и мотать не придётся.

        >Где то прочел: пока не знаешь как устроенны и работают простые библиотечные функции не используй их, а пиши свои реализации

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

        >Проверку входный данных - полезно, ЗАПОМНЮ!

        По идее, везде, где есть внешние данные, должны быть проверки или слои проверок для того, чтобы не ставить кордоны по периметру внутреннего кода. Сверху, снизу, сбоку и так далее. Защитному программированию вообще никто не учит, а жалко.

      • Проблема новичка , !*! ACCA, 23:55 , 21-Янв-22 (11)
        > Первый: "Как выглядит промышленный код?" По задумке выношу реализацию в отдельные функции

        Промышленный код выглядит, как дерьмо, размазаное по потолку криворукими обезьянами.


        > и в main оставляю только общую логику и организацию данных. На
        > данном этапе на простых программах это избыточный код, но может быть
        > такая привычка даст результаты в будущем?

        Результатом будет промышленный код. Писать нужно просто. Чем проще, тем лучше. Чтобы можно было с первого взгляда понять, что ты делаешь. Без углубления в общую логику и организацию данных.


        > Второй: "Как правильно учиться?" Где то прочел: пока не знаешь как устроенны
        > и работают простые библиотечные функции не используй их, а пиши свои
        > реализации". ПОДЧЕРКНУ: совет для стадии обучения. Мне он понравился вот и
        > леплю как могу.

        Мы поняли.
        Обрати внимание, что в моём примере использована только одна библиотечные функция (не считая печати) - strlen. И не написана ни одна новая.

        Всё остальное сделано [за кадром] средствами операционной системы.


        > Что думаете о выше поставленных вопросах?

        Научишься. Попробуй найти книгу https://search.rsl.ru/ru/record/01001496775

        И ещё - никогда не используй глобальные переменные.

        • Проблема новичка , !*! Конч, 16:51 , 30-Янв-22 (14)
          > И ещё - никогда не используй глобальные переменные.

          А goto ему можно использовать?

          • Проблема новичка , !*! ACCA, 11:19 , 09-Апр-22 (15)
            >> И ещё - никогда не используй глобальные переменные.
            > А goto ему можно использовать?

            Это не некропост, просто пришлось подумать.

            Если не использовать heap, а всю память брать из stack, то exception реализуется очень просто - переставляешь stack и выполняешь goto.

            Походу malloc - крайне вредная функция. Это же COMMON BLOCK из FORTRAN.

    • Проблема новичка , !*! Конч, 20:25 , 18-Янв-22 (7)
      А вот я терпеть не могу стиль с { на той же строке.
      Но это ладно, тут звезда сразу после типа - может подбить новичка думать, что звезда - часть типа.
      Да и по паре действий в каждом if внизу не особо нужны.

    • Проблема новичка , !*! Конч, 20:28 , 18-Янв-22 (8)
      Обычно учат вводить данные прямо с консольки, со stdin, в теории это должно чему-то научить, но по сути учит не умеющих в консольку людей ненавидеть консоль.
      • Проблема новичка , !*! Аноним, 17:27 , 22-Янв-22 (12)
        > Обычно учат вводить данные прямо с консольки, со stdin, в теории это
        > должно чему-то научить,

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

        • Проблема новичка , !*! Конч, 16:50 , 30-Янв-22 (13)
          >> Обычно учат вводить данные прямо с консольки, со stdin, в теории это
          >> должно чему-то научить,
          > не чимунибуть, а работать с стдин. вы плять хеловордисты не умеете и
          > элементарных консольных утилит написать, а уже передаете в поколение свою безмозглость.

          Не каждой программе суждено быть фильтром.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру