The OpenNET Project / Index page

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



"Проблема новичка "
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Проблема новичка "  +/
Сообщение от A6e3iana (ok), 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;
}

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения [Сортировка по ответам | RSS]

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


Ответить | Правка | Наверх | Cообщить модератору

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

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

Ответить | Правка | Наверх | Cообщить модератору
Ответы: #4

4. Сообщение от A6e3iana (ok), 15-Янв-22, 11:57   +/

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

Большое спасибо! Всё заработало! Даже обидно на невнимательности завалиться :(

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #3

5. Сообщение от ACCA (ok), 17-Янв-22, 21:09   +/
Хороший пример, как НЕ НУЖНО писать программы. Сравни с этим:


#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;
}

Ответить | Правка | Наверх | Cообщить модератору
Ответы: #6, #7, #8

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

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

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

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

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

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


Ответить | Правка | Наверх | Cообщить модератору
Родитель: #5 Ответы: #9, #11

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #5

8. Сообщение от Конч (?), 18-Янв-22, 20:28   +/
Обычно учат вводить данные прямо с консольки, со stdin, в теории это должно чему-то научить, но по сути учит не умеющих в консольку людей ненавидеть консоль.
Ответить | Правка | Наверх | Cообщить модератору
Родитель: #5 Ответы: #12

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

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

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

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

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

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6 Ответы: #10

10. Сообщение от Конч (?), 18-Янв-22, 20:41   +/
>затрагивают её поведение

Могут затрагивать.

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #9

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

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


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

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


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

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

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


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

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

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #6 Ответы: #14

12. Сообщение от Аноним (12), 22-Янв-22, 17:27   +/
> Обычно учат вводить данные прямо с консольки, со stdin, в теории это
> должно чему-то научить,

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #8 Ответы: #13

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

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #12

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

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #11 Ответы: #15

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

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

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

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

Ответить | Правка | Наверх | Cообщить модератору
Родитель: #14


Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




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

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