Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C]печать отсортированных чисел 
:(
    Опции темы
KatrinIceLand
  Дата 28.11.2007, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 16.3.2006

Репутация: нет
Всего: нет



Здравствуйте. Мне опять нужна ваша помощь. 
Программа для отгадывания правильного числа написана (guess.c). Дано число (secret number) и кто из участников ближе к правильному ответу, тот и побеждает. У каждого участника есть 3 попытки и не более для угадывания правильного числа. В текстовый файл сохраняются данные.

Вот программа guess.c
Код

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#define FALSE (0)
#define TRUE  (1)

// Important definitions
//
#define MAX_TRIES  (3)

typedef struct guess_record
{
    int uid;
    int tries;
    int guess;
} guess_record;

// check if a new guess is better than the old one
//
int is_better(int secret_number, int old_guess, int new_guess)
{
    int old_distance = secret_number - old_guess;
    if( old_distance < 0 ) old_distance = -old_distance;

    int new_distance = secret_number - new_guess;
    if( new_distance < 0 ) new_distance = -new_distance;

    if( new_distance < old_distance ) return 1;
    return 0;
}

// make a guess, if more tries are allowed
//
void make_a_guess(guess_record* guessrec, int secret_number, int guess)
{
    if( guessrec->tries < MAX_TRIES )
    {
        guessrec->tries = guessrec->tries + 1;
        if( is_better(secret_number, guessrec->guess, guess) )
        {
            guessrec->guess = guess;
        }
    }
}

// where all the work is done
//
int main(int argc, char** argv)
{
    int uid = -1;
    int nums[MAX_TRIES];
    int tries = 0;
    int secret_number = 0;
    guess_record* guessdb = NULL;
    int dbcount = 0;

    // get uid (remember getpwuid is the way to map uid -> user_name_str)
    //
    {
        uid = getuid();
    }

    // get the current tries
    //
    {
        char** trystr = &argv[1];
        int i;

        for(i = 0; *trystr != NULL; ++i, ++trystr)
        {
            nums[i] = atoi(*trystr);
            ++tries;
        }
    }

    if( tries == 0 )
    {
        printf("Usage: doguess guess1 [[guess2] ... [guess_MAX_TRIES]]\n");
        return -1;
    }

    // read the secret number
    //
    {
       FILE* inf = fopen("secretnum.txt", "rt");
       if( inf == NULL )
       {
           printf("The secret number file secretnum.txt must exist\n");
           return -1;
       }

       fscanf(inf, "%d\n", &secret_number);
       fclose(inf);
    }

 

    // read the guess db
    //
    {
       int i;
       // get the old records, with space allocated for one more

       FILE* inf = fopen("guesses.txt", "rt");
       if( inf == NULL )
       {
           printf("The db file guesses.txt must exist\n");
           return -1;
       }

       fscanf(inf, "%d\n", &dbcount);
       guessdb = (guess_record*)calloc( dbcount+1, sizeof(guess_record) );

       for(i = 0; i < dbcount; ++i) {
           fscanf(inf, "%d,%d,%d\n",
                  & (guessdb[i].uid),
                  & (guessdb[i].tries),
                  & (guessdb[i].guess));
       }
       fclose(inf);
    }

    // update the guess db
    //
    {
        int is_already_updated = FALSE;
        int i;

        // update in place, if already in db
        for(i = 0; i < dbcount; ++i)
        {
            if(guessdb[i].uid == uid)
            {
                int j;
                is_already_updated = TRUE;

                for(j = 0; j < tries; ++j)
                {
                    make_a_guess( &guessdb[i], secret_number, nums[j] );
                }
            }
        }

        // otherwise add to db
        if( ! is_already_updated )
        {
            int j;

            // add the initial guess
            guessdb[dbcount].uid = uid;
            guessdb[dbcount].tries = 1;
            guessdb[dbcount].guess = nums[0];

            // make remaining guesses
            for(j = 1; j < tries; ++j)
            {
                make_a_guess( &guessdb[dbcount], secret_number, nums[j] );
            }

            // include row in db
            ++dbcount;
        }
    }

    // write the updated guess db
    //
    {
       FILE* outf = fopen("guesses.txt", "wt");

       int i;
       fprintf(outf, "%d\n", dbcount);

       for(i = 0; i < dbcount; ++i) {
           fprintf(outf, "%d,%d,%d\n",
                   guessdb[i].uid,
                   guessdb[i].tries,
                   guessdb[i].guess);
       }

       fclose(outf);
    }

    return 0;
}


Преподователи не любят читать этот текстовый файл (guesses.txt) потому что он не отсортированный и использует идентификационные номара юзеров вместо имен.

Надо написать программу на С, файл назвать printguess.c, которая будет печатать 5 наиболее верных ответа с именами (вместо идентификационных номеров юзеров) кто отгадывал. Ограничения доступа к файлам должны быть:

"secretnum.txt" хранит точные данные дней и только программа имеет доступ к этим данным (contains the correct number of days and should only be accessible by the program itself.)

"guesses.txt" только программа имеет доступ к этому файлу (should only be accessible by the program itself.)

"mkguess" выполнять программу может только юзеры которые имеют доступ к отгадыванию чисел. ( the executable should only be runnable by users that are allowed to compete. Also, because the program may contain exploitable vulnerabilities, it should not run with administrative privileges, but with less privilege.)

(к сожалению концовка мне не понятна, пожалуйста посмотрите в английской версии).

Make use of the qsort standard C function and the getpwuid Unix routine to do the work.  
To make use of qsort, you need a comparison function.  It will look something like the following:

функция для сравнения чисел в дальнейшем для установления 5-ти победителей:
Код


int secret_number;
 
int guess_distance(int guess)
{
    int distance = secret_number - guess;
    if( distance < 0 ) distance = -distance;
    return distance;
}
 
int compare_guesses(const void* one, const void* one)
{
    return guess_distance(((guess_record*)one)->guess) 
         - guess_distance(((guess_record*)two)->guess);
}
 


 smile 

Это сообщение отредактировал(а) KatrinIceLand - 29.11.2007, 19:44
--------------------
[... кто изобрел математику? А зачем?...
PM MAIL   Вверх
KatrinIceLand
Дата 30.11.2007, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 16.3.2006

Репутация: нет
Всего: нет



Уважаемые программисты, ну давайте попробуем что-нибудь написать, пожалуйста...

Наверняка кто-нибудь знает как вывести данные на принтер. 

Добавить функцию для сравнения номеров, выбрать пять победителей (те чьи номера ближе к загаданному номеру (secret number)) и вывести все это на печать.


--------------------
[... кто изобрел математику? А зачем?...
PM MAIL   Вверх
GIK
Дата 1.12.2007, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Добрый человек
**


Профиль
Группа: Участник
Сообщений: 985
Регистрация: 3.6.2005
Где: я только не небыв ал

Репутация: 4
Всего: 14



Лично мне код не понятен, мне легче самому написать алгоритм, чем копаться в твоем коде  smile 


--------------------
Математика=>пиво=> програмирование, три вещи последовательны и совместимы !!!
Программирование - это не деятельнось! Программирование - это состояние души!
Бог - самый крутой программист.
PM MAIL ICQ   Вверх
KatrinIceLand
Дата 1.12.2007, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 16.3.2006

Репутация: нет
Всего: нет



Цитата(GIK @  1.12.2007,  09:03 Найти цитируемый пост)
Лично мне код не понятен, мне легче самому написать алгоритм, чем копаться в твоем коде    


А что конкретно не понятно? 

В двух словах:

int is_better функция сравнивает результаты если старый угаданный номер ближе к секретному номеру или нет.

- секретный номер дан.

- самые правильные попытки сохранены в БД

Теперь все это из текстового файла надо вывести на печать в более читаемом виде.
--------------------
[... кто изобрел математику? А зачем?...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0663 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.