#1 2014-10-02 11:12:33

motin.maxim
Учасник
З Киев
Зареєстрований: 2014-08-01
Повідомлень: 17
Сайт

Сравнение двух массивов char

Часто появляется задача сравнения двух массивов char. В моем слуаче было необходимо создать функцию которая выдавала 1 если хоть один из двух массивов эквивалентен на заданному. Ок. Пишем скетч. Для начала будем проверять сам алгоритм, поэтому сверка со вторым масивом закоменчена.

char n_tel[]="12345";
char root_tel_one[]="12345";
char root_tel_two[]="12346";
void setup() {
  Serial.begin(9600);
}
boolean check_num()
{
  boolean check1=0;
  boolean check2=0;
  
  int i=0;
  while (n_tel[i]==root_tel_one[i]) i=i+1;
  if (i==sizeof(n_tel)) check1=1;
  /*
  int k=0;
  while (n_tel[k]==root_tel_two[k]) k=k+1;
  if (k==sizeof(n_tel)) check2=1;
  */
  Serial.println(check1);
  Serial.println(check2);
  return check1||check2;
}

void loop() {
  
  Serial.println(check_num());
  delay(2000);
 
}

Ны выхлопе получаем:
1
0
1
Это хорошо и правильно. Раскоментим второй масив.
Получится это:

char n_tel[]="12345";
char root_tel_one[]="12345";
char root_tel_two[]="12346";
void setup() {
  Serial.begin(9600);
}
boolean check_num()
{
  boolean check1=0;
  boolean check2=0;
  
  int i=0;
  while (n_tel[i]==root_tel_one[i]) i=i+1;
  if (i==sizeof(n_tel)) check1=1;

  int k=0;
  while (n_tel[k]==root_tel_two[k]) k=k+1;
  if (k==sizeof(n_tel)) check2=1;

  Serial.println(check1);
  Serial.println(check2);
  return check1||check2;
}

void loop() {
  
  Serial.println(check_num());
  delay(2000);
 
}

Ок, запускаем. На выхлопе:
0
0
0
Вопрос, где я туплю?

Неактивний

#2 2014-10-02 15:21:05

admin
Administrator
З Киев
Зареєстрований: 2014-06-09
Повідомлень: 67

Re: Сравнение двух массивов char

Мне  кажется так сравнивать не корректно. Нужно в условии while поставить проверку на выход за пределы массива, типа:

if(i==sizeof(n_tel))
    break;

Неактивний

#3 2014-10-02 16:01:52

motin.maxim
Учасник
З Киев
Зареєстрований: 2014-08-01
Повідомлень: 17
Сайт

Re: Сравнение двух массивов char

admin пише:

Мне  кажется так сравнивать не корректно. Нужно в условии while поставить проверку на выход за пределы массива, типа:

if(i==sizeof(n_tel))
    break;

Как вариант, спасибо. Но вродебы такого произойти не может, сравниваются два одинаковых по размеру массива. Если такое написать допустим просто на С, думаю будет работать.

Неактивний

#4 2014-12-02 12:01:51

Павел
Учасник
Зареєстрований: 2014-12-02
Повідомлень: 1

Re: Сравнение двух массивов char

motin.maxim пише:

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

Это утверждение неверно, т.к. на C массив это указатель на его первый элемент, если он задан статически (как в этом примере), то его размер знает компилятор на момент сборки, поэтому можно использовать sizeof(n_tel)/sizeof(char). Но компилятор не будет проверять выход за границы массива. Т.е. если строки будут одинаковые - программа пойдет дальше проверять байты (на настольном ПК скорее всего закончится segmentation fault - т.е. попытка прочитать память, которая нам не принадлежит).
И, кстати это все-равно плохой пример, т.к. в 99% случаев сравнивать (в реальной программе) придется динамические строки, о размере которых не знает даже компилятор.
C-строки характеризуются как раз тем, любую строку завершает символ '\0' (числовое значение - 0x00). поэтому функцию сравнения можно организовать следующим образом:

int strcheck(char *str1, char *str2){
  int i = 0;
  while(str1[i] != '\0' && str2[i] != '\0'){
    if(str1[i] != str2[i])
      return 0;
    i++;
  }
  //Если мы вышли из цикла значит одну из строк мы перебрали до конца
  if(str1[i] == '\0' && str2[i] == '\0')
    return 1;
  return 0;
}

Функция вернет 1 если строки одинаковые, или 0 - если он отличаются (как по содержимому, так и по длине).
На лаконичность/красоту кода не претендую, хотел только показать как можно работать со строками не зная (заранее) их длину.

Остання редакція Павел (2014-12-02 12:04:10)

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму