2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Еще одна задачка из Кернигана-Ритчи
Сообщение29.07.2012, 23:32 
Аватара пользователя


26/02/11
332
Напишите функцию htoi(s), которая преобразует строку шестнадцатеричных цифр (учитывая необязательные элементы 0х или 0Х) в ее целочисленный
эквивалент. В число допустимых цифр входят десятичные цифры от 0 до 9, а также
буквы a-f и A-F.


Я так понимаю, по условию задачи нужно написать программу перевода чисел из 16-ой с.с в 10-ую? Тогда какое решение хотели увидеть авторы? Неужели все так просто?
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>

int htoi(int a);

int main()
{
    int x;
    htoi(x);
   
    getch();
    return 0;
}

int htoi(int a)
{
    scanf("%x", &a);
    printf("%d", a);
    return a;
}

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 01:00 
Заслуженный участник


11/05/08
32166
Я в Сях не разбираюсь, но авторы хотели наверняка не этого. Они наверняка хотели, чтоб Вы эмулировали встроенную функцию scanf.

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 01:27 
Заслуженный участник
Аватара пользователя


23/07/08
10652
Crna Gora
Dosaev писал(а):
в 10-ую?
Нет, не в десятичную. Надо перевести строку (const char *) в int, то есть в тот формат, в котором в памяти хранятся целые числа (скажем, 32-разрядные). Они ведь не в десятичной форме там хранятся.

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 17:12 
Аватара пользователя


26/02/11
332
svv в сообщении #600856 писал(а):
Нет, не в десятичную. Надо перевести строку (const char *) в int, то есть в тот формат, в котором в памяти хранятся целые числа (скажем, 32-разрядные). Они ведь не в десятичной форме там хранятся.

Не понял. В двоичные что ли? :shock:

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 17:14 
Заслуженный участник


04/05/09
4582
Во внутреннее представление - в виде переменной типа int, или возвращаемое значение функции типа int. А двоичное оно, или какое ещё - неважно (хотя на современных платформах - двоичное).

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 17:48 
Аватара пользователя


26/02/11
332
То есть массив перевести в переменную типа int?

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 18:52 
Заслуженный участник
Аватара пользователя


23/07/08
10652
Crna Gora
Да. Строка — это массив символов. Её нужно перевести в переменную типа int.

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 19:41 
Аватара пользователя


26/02/11
332
Вот немного состряпал. Это недоработка, она даже не работает по той причине, что pow возвращает float-ское значение. Как мне преобразовать значение dec? Или вообще я не то делаю? И как быть с буквами a b c d e f?
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>
#include <string.h>

#define MAXLINE 1024

void getline(char str[], int lim);
int htoi(char str[]);

int main()
{
    char str[MAXLINE];
    getline(str, MAXLINE);
    printf("%d", htoi(str));

    getch();
    return 0;
}
/* старая функция для ввода массива */
void getline(char str[], int lim)
{
    int c, i;
   
    for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
          str[i] = c;
         
    if (c == '\n')
       str[i] = c;
   
    ++i;
    str[i] = '\0';
}
/* вот искомая функция */
int htoi(char str[])
{
    int dec = 0;
   
    int length = strlen(str);
    length--;
   
    int i;
    for(i = 1; i <= length; ++i) {
          /* switch (str[i-1])
          {
                 case 'a': str[i-1] = ; // вот тут как быть, если символ одна из букв?
                 case 'b': str[i-1] = ;
                 case 'c': str[i-1] = ;
                 case 'd': str[i-1] = ;
                 case 'e': str[i-1] = ;
                 case 'f': str[i-1] = ;
          } */

          str[i-1] -= '0';
          dec += str[i-1]*pow(16, length - i);
    }
   
    return dec;
}

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение30.07.2012, 21:17 
Заслуженный участник


28/04/09
1933
Интересно, что код символа '0' Вы догадались вычесть, а код символа 'a' $\text{---}$ нет. Ведь буквы (обычно) идут в таблице символов тоже по порядку (алфавитному). Впрочем, даже если бы это и было не так, Ваш вариант с использованием конструкции switch ... case вполне адекватен (только не стоит забывать про слово break). Что же касается возвращаемого функцией pow значения, то его, конечно, можно было бы преобразовать к целочисленному, используя приведение типов или какую-нибудь функцию математической библиотеки (округление, взятие целой части и т.п.), однако в данном случае гораздо лучше эту функцию и вовсе не использовать, а лишь заметить, что $\overline{a_n a_{n-1}\ldots a_2 a_1 a_0}=10\cdot \overline{a_n a_{n-1}\ldots a_2 a_1}+a_0$.
P.S. К нумерации с 0 еще не привыкли?

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 09:14 
Аватара пользователя


26/02/11
332
EtCetera в сообщении #601229 писал(а):
заметить, что $\overline{a_n a_{n-1}\ldots a_2 a_1 a_0}=10\cdot \overline{a_n a_{n-1}\ldots a_2 a_1}+a_0$.


Так все равно же придется 10ку возводить в степень, т.е использовать функцию pow для представления числа $\overline{a_na_{n-1}...a_1a_0} = a_n \cdot 10^n + a_{n-1} \cdot 10^{n-1} + ... + a_1 \cdot 10 + a_0.$ Нет?

-- Вт июл 31, 2012 09:21:05 --

EtCetera в сообщении #601229 писал(а):
P.S. К нумерации с 0 еще не привыкли?

Может быть не привык, но в данной программе удобно с 1 по-моему, там все равно 0-ой элемент используется.

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 09:33 
Аватара пользователя


30/09/10
119
Код:
M = 0;
for(i=0; str[i]!='\0'; i++) {
  c = str[i];
  if (c=='x' || c=='X' && M==0) continue;
  if (c>='0' || c<='9') c -= '0';
  else if ('a' <= c && c<='f') c = 10 + c - 'a';
  else if ('A' <= c && c<='F') c = 10 + c - 'A';
  else break;
  M = M*16 + c;
}

Как-то так

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 09:40 
Аватара пользователя


26/02/11
332
Хм, лаконично. :|
Спасибо.

-- Вт июл 31, 2012 10:39:26 --

Day, странно, но выдает всегда 0. :-( В чем причина? Никак не могу понять...
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>

#define MAXLINE 1000

void getline(char s[], int lim);
int htoi(char s[]);

int main()
{
  char chislo[MAXLINE];
 
  getline(chislo, MAXLINE);
  printf("%d", htoi(chislo));
 
  getch();
  return 0;
}

/* íó ýòî ñòàðàÿ ãåòëàéíîâñêàÿ ôóíêöèÿ äëÿ ââîäà ìàññèâà */
void getline(char s[], int lim)
{
    int c, i;
   
    for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
          s[i] = c;
         
    if (c == '\n')
       s[i] = c;
   
    ++i;
    s[i] = '\0';
}

int htoi(char s[])
{
     int c, M, i;
     
     M = 0;
     
     for(i = 0; i != '\0'; i++) {
           c = s[i];
         if(c == 'x' || c == 'X' && c == '0') continue;
         if(c >= '1' && c <= '9') c -= '0';
         else if(c >= 'a' && c <= 'f') c = 10 + c -'a';
         else if(c >= 'A' && c <= 'F') c = 10 + c - 'A';
         else break;
         M = M*16 + c;
     }    
    return M;
}

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 10:52 


20/04/12
7
Смущает строка
Код:
if(c == 'x' || c == 'X' && c == '0') continue;

А именно: "&&". с не может равняться 2 одновременно разным значениям.
И цикл for написан неверно, т.к. он не выполнит ни одной итерации. Ибо 0 ='\0'. Он в него даже не зайдет ни разу.
Замените цикл на while. Чтоб итератором был указатель на текущий символ. Тогда вы сможете обработать последовательность "0x". И не забудьте про то, что 0 тоже число, а не только встречается в последовательности "0x".

 Профиль  
                  
 
 Re: Еще одна задачка из Кернигана-Ритчи
Сообщение31.07.2012, 14:48 
Аватара пользователя


26/02/11
332
Ух! Вроде все работает. Спасибо всем за помощь. :wink:
код: [ скачать ] [ спрятать ]
Используется синтаксис C
int htoi(char s[])
{
     int c, M, i;
     
     M = 0;
     
     for(i = 0; s[i] != '\0'; i++) {
         if(s[i] == '0') {
              ++i;
              if (s[i] == 'x' || s[i] == 'X') ++i;
         }
         c = s[i];
         if(c >= '1' && c <= '9') c -= '0';
         else if(c >= 'a' && c <= 'f') c = 10 + c -'a';
         else if(c >= 'A' && c <= 'F') c = 10 + c - 'A';
         else break;
         M = M*16 + c;
     }    
    return M;
}

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group