Показаны сообщения с ярлыком студентам. Показать все сообщения
Показаны сообщения с ярлыком студентам. Показать все сообщения

четверг, 17 мая 2012 г.

Решение задачки на Си


Решил задачку для студента Пермского политеха, вот ниже решение без матчасти и в упрощенной постановке (чтоб не показывать как нашел точку пересечения эллипса с окружностью, в этом соль решения). Определяем принадлежность точки областям А или B.

#include <stdlib.h>
#include <stdio.h>    // чтоб обеспечить ввод/вывод
#include <math.h>     // чтоб использовать стандартные математические функции
#include <windows.h> // Чтоб русифицировать вывод в консоль, в окне консоли шрифт поменять

int blnCircle(double x,double  y,double R,double xo,double yo );
int blnEllips(double x,double  y,double a,double b,double xe,double ye);

int main()
{
    //Чтоб русифицировать вывод в консоль, в окне Свойства консоли шрифт поменять на TT
    // в аргументах кодировка файла для UTF-8 ~ 65001, а для cp1251 ~ 1251
    SetConsoleCP(65001);
    SetConsoleOutputCP(65001);

    double R,x,y,a,b,xo,yo,xe,ye;
    double t1,t2,c;     // Промежут. данные для расчета центра эллипса

    do
    {
        printf("Введите радиус окружности (R>=15):\n");
        scanf("%lf",&R);
    }
    while(R<15);

    do
    {
        printf("Введите значения полуосей эллипса a и b (b>a, 2b>=40 ):\n");
        scanf("%lf%lf",&a ,&b) ;
    }
    while(b<=a || 2.0*b<40);

    printf("Введите координаты точки для проверки, принадлежности её областям A или B\n");
    scanf("%lf%lf",&x ,&y) ;

    /// Определим центр окружности
    xo=(38-sqrtf(-900+60*R));
    yo=(R-30);

    /// Определим центр эллипса
    c=sqrt(pow(b,2)-pow(a,2));
    t1=pow(40.0-b+c,2);
    t2=pow(c-40+b,2);
    xe=9.0 - sqrt((4.0*t1*t2-pow(t1+t2-4*b*b,2))/(-16.0*pow(b,2)));
    ye=40.0-b;




    if( blnEllips(x,y,a,b,xe,ye) && x<=0 && y>=9 && !blnCircle(x,y,R,xo,yo))
        printf ("Точка принадлежит области A\n");
    else if(!blnEllips(x,y,a,b,xe,ye) && blnCircle(x,y,R,xo,yo) && y>=0 && x>=0 && y<=9)
        printf("Точка принадлежит области B\n");
    else
        printf("Точка не принадлежит областям A и B\n");

    system("pause"); // Останов программы под Windows, чтоб успеть результат посмотреть
    return 0;
}


/// Проверка принадлежности точки области ограниченой окружностью и получения её цнтра
int blnCircle(double x,double  y,double R,double xo,double yo)
{
    return (pow((x-xo),2)+pow(y-yo,2)<=pow(R,2));
}

/// Проверка принадлежности точки области внутри эллипса и его центр
int blnEllips(double x,double y,double a,double b,double xe,double ye)
{
    return ( pow(x-xe,2)/pow(a,2)+pow(y-ye,2)/pow(b,2)<=1 );
}


вторник, 15 марта 2011 г.

Отображение кириллических символов в консоли

1. Вариант
Использовать широкие символы
Редактор кода настраивается на ввод символов в кодировке UTF-8
Settings -> Editor… -> General Settings -> Other settings -> Encoding и выбрать UTF-8.
Теперь в тексте программы один символ кодируется двумя байтами, тип которого соответствует wchar_t (тип данных стандарта ANSI/ISO C для представления широких символов). Теперь в программе надо использовать функции, которые умеют обрабатывать wchar_t символы и корректно выполнять ввод/вывод. Обычно имена функций работающих с wchat_t начинаются с символа ‘w’, стоящим перед именем аналогичной функции, но работающей с char, например,
int wprintf( const wchar_t *format [, argument]... ) ; /*аналогична printf */
int wscanf( const wchar_t *format [, argument]... ) ; /* scanf */

В Windows API, тип wchar_t имеет размер 16 бит.
В GNU/Linux тип wchar_t имеет размер 32 бита.

Пример:
/*Компилятор MinGW*/
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

int main()
{
setlocale(0,".866");/*Локаль, без этой строки не будет работать*/
wprintf(L"Привет!\n"); /*L – указываем, что используются широкие символы в строке*/
return 0;
}

2. Вариант
Использовать Win32Api функцию CharToOem
Текст программы имеет кодировку WINDOWS-1251 или ANSI, функция CharToOem вызывается обычно перед выводом в консоль какого-либо текста с кириллическими символами.

Пример:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
char s[] = "Текст";
CharToOem(s,s);/*Перекодируем s, после этого вызова s меняет своё значение*/
printf("%s",s);
return 0;
}

3. Вариант
Использование шрифта Lucida Console в консоли
// установить вручную шрифт Lucida Console в свойствах окна консоли
// и запомнить это для всех окон с этим именем
// записать в начале программы строку
#include <windows.h>
// записать в начале функции main ()
// две следующих строки
SetConsoleCP(1251);
SetConsoleOutputCP(1251);

4. Вариант
Использовать опций компилятора для перекодировки текста программы из UTF-8 в CP866. Понятно, что можно использовать и другое направление перекодировки, типа WINDOWS-1251 в CP866. В консоли должна быть доступна команда iconv.
В командной строке делаем, например, так
gcc -finput-charset=UTF-8 -fexec-charset=CP866 main.c -o main

В CodeBlocks можно прописать эти опции в параметры компиляции для проекта
Project -> Build options -> Compiler settings -> Other options
Записываем строку:
-finput-charset=UTF-8 -fexec-charset=CP866

5. Вариант
Если используется компилятор от Microsoft (cl.exe), то достаточно прописать только локаль, строка в функции main():
setlocale(0,””);