Error incompatible types got constant string expected char

Александр Яшин писал(а):Так компилируется, но в Symbol нечитаемый символ!

Александр Яшин писал(а):Так компилируется, но в Symbol нечитаемый символ!

Без примера тут будет проблематично разобраться. «Читаемый» и «нечитаемый» — понятия относительные, зависят от того как выводить, куда выводить и под какой ОС всё это происходит. Если выводить на форму — то для читабельности нужно его преобразовывать обратно в UTF-8 вне зависимости от платформы, в консоль под Linux — тоже чаще всего в UTF-8, в в консоль под Windows — в кодировку OEM Cyrillic (866).

Александр Яшин писал(а):Похоже тип char в Unicode поддерживается только для кодов < 128

Тип char и Unicode — это две разные вещи. Char — это кусочек памяти размером ровно в один байт. Юникод — это способ кодирования символов, его конкретная разновидность, UTF-8, требует от одного до четырёх байт памяти на один символ. По одному байту — на символы латиницы, для совместимости, на кириллицу — по два, на восточные кодировки — 3 и 4 байта. Разумеется, что любой символ UTF-8 не влезет в один байт переменной типа char. Это всё равно что переливать воду из четырёхлитрового бочонка в литровую банку. Если в бочонке было меньше литра (читай «< 128») — наше счастье, но полагаться на это никоим образом нельзя.

И кстати, можете заглянуть в исходники и посмотреть, что такое TUTF8Char :) Ctrl+щелчок мышкой на типе переменной.

Код: Выделить всё
TUTF8Char = String[7];

Символьные типы данных

В Lazarus имеется символьный тип Char. Переменная такого типа занимает ровно один байт памяти и может содержать любой ASCII — символ. Русскому языку с этим типом не повезло — поскольку символы кириллицы занимают по 2 байта, использовать этот тип с русскими буквами нельзя. Давайте откроем Lazarus с новым проектом. Если Lazarus у вас уже загружен, закройте старый проект командой Файл -> Закрыть, и создайте новый проект командой Проект -> Создать проект -> Приложение. Сразу же сохраните проект в папку 05-01 там, где вы храните все проекты лекций, проекту дайте имя MyStrings, и не забудьте назвать модуль главной формы Main, а саму форму fMain. Пусть это войдет у вас в привычку. Как всё это делается, вы должны знать по предыдущим лекциям. Не вздумайте давать своим проектам имена, используя ключевые (зарезервированные) слова.
Например, нельзя давать проекту или модулю имя Strings, поскольку это слово зарезервировано, но MyStrings можно.

Прямо посреди формы установите кнопку TButton, дважды нажмите на нее, чтобы сгенерировать обработчик OnClick. В обработчике создадим раздел переменных var, укажем там одну переменную типа Char, и запрограммируем следующий код:

procedure TfMain.Button1Click(Sender: TObject);
var
  ch1: Char; //переменная символьного типа
begin
  ch1:= 'Z';
  ShowMessage(ch1);
end;
    

Как видим, здесь мы переменной ch1 присвоили значение — символ «Z«. Запомните правило:

Символы и строки в Lazarus должны быть заключены в одинарные кавычки. Если требуется ввести в текст одинарную кавычку (например, в слове can’t), то следует указать две таких одинарных кавычки, которые также заключены в одинарные кавычки.

Например:

Mystring:= 'I can' + '''' + 't';
    

Этот пример выполнять не нужно, он просто демонстрирует использование кавычек в строковых выражениях, и возможность в выражении соединять несколько строк в одну с помощью знака «+«. Однако вернемся к нашему проекту. После того, как мы присвоили символьной переменной большую английскую букву «Z», мы вывели содержимое переменной с помощью строки

Сохраните проект, скомпилируйте его и выполните. Когда программа с кнопкой появится на экране, нажмите нашу единственную кнопку — выйдет сообщение с буквой «Z»:

Вывод символа

Рис.
5.2.
Вывод символа

Таким образом, мы можем работать с отдельными символами. Однако если вы исправите код, и вместо буквы «Z» в строке

укажете русский символ, то при попытке скомпилировать и запустить проект выйдет ошибка «Error: Incompatible types: got «Constant String» expected «Char»» — несовместимость типов String (строка) и Char (символ). Поскольку русские буквы занимают по два байта, Lazarus их считает строкой символов. Однако это не значит, что мы совсем не имеем возможности работать с отдельными символами кириллицы.

Ранее упоминалось, что в Lazarus используется формат UTF8. Для поддержки этого формата были разработаны расширенные типы данных, в том числе и символьные. Так, имеется тип TUTF8Char, который позволяет работать с любыми отдельными символами, в том числе и русскими. Имеет смысл всегда использовать его вместо стандартного Char. Но для этого нам нужно будет подключить модуль LCLType, где этот тип описан.

Перейдите в редактор кода и пролистайте код модуля вверх. Там вы увидите раздел uses (англ. use — использовать), где перечислены подключенные модули. Нам нужно поставить после последнего модуля запятую и добавить наш подключаемый модуль:

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  LCLType;
    

Если строка получается длинной, то после запятой можно переносить текст на другую строку.

Теперь вернемся к обработчику нажатия на кнопку и переделаем его:

procedure TfMain.Button1Click(Sender: TObject);
var
  ch1: Char;
  ch2: TUTF8Char;
begin
  ch1:= 'Z';
  ch2:= 'Я';
  ShowMessage(ch1);
  ShowMessage(ch2);
end;
    

Теперь всё сработает как надо, и русский символ «Я» выйдет так же, как английский «Z«.

Однако, это еще не всё. Символы можно вводить, указывая их номер в таблице символов. Для этого перед номером нужно указать символ «#«, например:

Под номером 90 находится буква Z в таблице символов, так что результат не изменится. Также в строковых выражениях можно указывать и специальные символы. Например, символ под номером 13 — это символ перехода на другую строку. Давайте снова немного изменим код:

procedure TfMain.Button1Click(Sender: TObject);
var
  ch1: Char;
  ch2: TUTF8Char;
begin
  ch1:= #90;  //буква Z
  ch2:= 'Я';
  ShowMessage(ch1 + #13 + ch2); //вывод двухстрочного сообщения
end;
    

Сохраните проект, скомпилируйте и запустите на выполнение. Теперь содержимое двух символьных переменных выходит в одном сообщении, но каждое на своей строке.

Topic: Char constant  (Read 1236 times)

There is a declaration

 CONST  hor=’Ä’;

and later

FillChar(zo[1], z_breite, hor); 

Compilermessage:    Error: Incompatible type for arg no. 3: Got «Constant String», expected «Char»

Why is   CONST  hor=’Ä’;  not a constant for a character but for a string??


Logged


« Last Edit: February 16, 2021, 07:04:47 pm by Handoko »


Logged


Thank you,

you are right.
If i replace  hor=’Ä’ by hor=’A’ the error does not occur.

I need these characters for graphic symbols.


Logged


[…] Why is   CONST  hor=’Ä’;  not a constant for a character but for a string??

That is an encoding issue. You have probably saved your file in UTF-8. When you

writeLn(sizeOf(hor))

you will see this is two Bytes, but a

char

is a 1-Byte-sized quantity. If I save your code (for example) as a “Latin-1” encoded file, it will compile without issues.

Alternatively, you may specify

{$mode DelphiUnicode}

before

program

. This will make

char

values occupy two Bytes.
Or, what Handoko suggested. That’s probably the easiest method.


Logged



Logged


If you use Lazarus IDE, then by default everything you type is in UTF8 encoding.
‘Ä’ in UTF8 consist of more than 1 byte (2, I guess), so from the point of the compiler it is a string.

If you use the FP IDE then ‘Ä’ is stored as a single byte, so the compiler can treat it as a Char.

Solutions rahter depend on wether this is a console application or a GUI application and wether or not you use the Lazarus IDE as your editor or the FP IDE (or Notepad or something else).

Bart


Logged


Hi!

Ä Ansi  $C4        1 Byte
Ä Utf-8 $C384     2 Bytes

Winni


Logged


Deniseo

2 / 2 / 1

Регистрация: 23.04.2015

Сообщений: 56

1

Преобразование определенных букв из прописных в строчные

25.03.2016, 19:46. Показов 2731. Ответов 10

Метки нет (Все метки)


Задача: Составить программу, которая преобразует буквы «А», «Б», «В» из прописных букв в строчные.

У меня получилось только это:

Delphi
1
2
3
4
5
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption:=UTF8LowerCase(Edit1.Text);
  Label2.Caption:=UTF8UpperCase(Edit1.Text);
end;

Как сделать программу надлежащим образом, как сказано в задачи?

Добавлено через 29 минут
Есть наглядный пример под delphi 6. Может кто докумекает и переделает под Lazarus

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
s:string;
begin
s:=edit1.Text;
for i:=1 to length(s) do
case s[i] of
'А':s[i]:='а';
'Б':s[i]:='б';
'В':s[i]:='в';
end;
label1.Caption:=s;
end;

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Пытливый

3295 / 1977 / 635

Регистрация: 29.05.2013

Сообщений: 8,553

25.03.2016, 19:50

2

Простейший вариант:

Delphi
1
2
Edit1.Text := StringReplace(Edit1.Text, 'А', 'а', [rfReplaceAll]);
Edit1.Text := StringReplace(Edit1.Text, 'Б', 'б', [rfReplaceAll]);

… и т.д.



0



quwy

Native x86

Эксперт Hardware

5175 / 3022 / 874

Регистрация: 13.02.2013

Сообщений: 9,635

25.03.2016, 19:51

3

Delphi
1
2
3
4
5
6
7
8
var
  i: Integer;
begin
  s:= 'АБВГДЕ';
  for i:= 1 to Length(s) do
    if CharInSet(s[i], ['А', 'Б', 'В']) then
      s[i]:= AnsiLowerCase(s[i])[1];
  ShowMessage(s);



0



Deniseo

2 / 2 / 1

Регистрация: 23.04.2015

Сообщений: 56

25.03.2016, 20:03

 [ТС]

4

Моя методичка не знает что такое «StringReplace» и «rfReplaceAll»(да и сам я не знаю что это вообще)

(

Взято из методичке)Можно ли реализовать по этим процедурам и функциям?
Процедуры: Delete, Insert, Str, Val
Функции: Copy, Concat, Lenght, Pos, UpCase

Добавлено через 1 минуту

Цитата
Сообщение от quwy
Посмотреть сообщение

Delphi
1
2
3
4
5
6
7
8
var
  i: Integer;
begin
  s:= 'АБВГДЕ';
  for i:= 1 to Length(s) do
    if CharInSet(s[i], ['А', 'Б', 'В']) then
      s[i]:= AnsiLowerCase(s[i])[1];
  ShowMessage(s);

Ошибка

Delphi
1
Error: Identifier not found "CharInSet"



0



quwy

Native x86

Эксперт Hardware

5175 / 3022 / 874

Регистрация: 13.02.2013

Сообщений: 9,635

25.03.2016, 20:05

5

Цитата
Сообщение от Deniseo
Посмотреть сообщение

Процедуры: Delete, Insert, Str, Val
Функции: Copy, Concat, Lenght, Pos, UpCase

Обязательно использовать их все?
UpCase, кстати, с кириллицей не работает.

Добавлено через 24 секунды

Цитата
Сообщение от Deniseo
Посмотреть сообщение

unit1.pas(51,8) Error: Identifier not found «CharInSet»

Уточняйте в следующий раз версию Delphi.

Delphi
1
if s[i] in ['А', 'Б', 'В'] then



0



Deniseo

2 / 2 / 1

Регистрация: 23.04.2015

Сообщений: 56

25.03.2016, 20:20

 [ТС]

6

Цитата
Сообщение от quwy
Посмотреть сообщение

Обязательно использовать их все?
UpCase, кстати, с кириллицей не работает.

Добавлено через 24 секунды

Уточняйте в следующий раз версию Delphi.

Delphi
1
if s[i] in ['А', 'Б', 'В'] then

Не обязательно, но нужно как то это реализовать по процедурам и функциям которые указаны методичке.

Кстати, ошибка осталась, только уже другая
Работаю в Lazarus 1.4.4

Delphi
1
Error: Ordinal expression expected

Добавлено через 4 минуты
UpCase отображает кириллицу вот таким способом

Delphi
1
2
3
uses LCLProc;
::code
UTF8UpperCase;

Добавлено через 6 минут
Я видимо не в тот раздел обратился с этим вопросом?
Что мне щас делать, пересоздавать тему в разделе «Lararus» или все таки помогут тут?



0



unifikator

500 / 356 / 231

Регистрация: 29.03.2015

Сообщений: 675

25.03.2016, 20:28

7

Код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
s:string;
begin
s:=edit1.Text;
for i:=1 to length(s) do
case s[i] of
'А':s[i]:='а';
'Б':s[i]:='б';
'В':s[i]:='в';
end;
label1.Caption:=s;
end;



0



Deniseo

2 / 2 / 1

Регистрация: 23.04.2015

Сообщений: 56

25.03.2016, 20:31

 [ТС]

8

Цитата
Сообщение от unifikator
Посмотреть сообщение

Код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
s:string;
begin
s:=edit1.Text;
for i:=1 to length(s) do
case s[i] of
'А':s[i]:='а';
'Б':s[i]:='б';
'В':s[i]:='в';
end;
label1.Caption:=s;
end;

Может в вашем delphi работает, но в моем лазарусе не хочет

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
Компиляция проекта, цель: project1.exe: Код завершения 1, ошибок: 11
unit1.pas(52,5) Error: Constant and CASE types do not match
unit1.pas(52,5) Error: Ordinal expression expected
unit1.pas(52,12) Error: Incompatible types: got "Constant String" expected "Char"
unit1.pas(53,5) Error: Constant and CASE types do not match
unit1.pas(53,5) Error: Ordinal expression expected
unit1.pas(53,5) Error: duplicate case label
unit1.pas(53,12) Error: Incompatible types: got "Constant String" expected "Char"
unit1.pas(54,5) Error: Constant and CASE types do not match
unit1.pas(54,5) Error: Ordinal expression expected
unit1.pas(54,5) Error: duplicate case label
unit1.pas(54,12) Error: Incompatible types: got "Constant String" expected "Char"

Начинает ругаться с 9 строчки вашего кода



0



500 / 356 / 231

Регистрация: 29.03.2015

Сообщений: 675

25.03.2016, 20:38

9

Мой код работает в Delphi 6. Правильно, что пересоздали тему в разделе «Форум Lazarus».



0



volvo

Супер-модератор

Эксперт Pascal/DelphiАвтор FAQ

32451 / 20945 / 8105

Регистрация: 22.10.2011

Сообщений: 36,213

Записей в блоге: 7

25.03.2016, 21:39

10

Лучший ответ Сообщение было отмечено Deniseo как решение

Решение

Цитата
Сообщение от Deniseo
Посмотреть сообщение

Может в вашем delphi работает

Это работает в Лазарусе:

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
procedure TForm1.Button1Click(Sender: TObject);
var
  s, ch: string;
  i: integer;
begin
  s := Edit1.Text;
  for i := 1 to UTF8Length(s) do
  begin
    ch := UTF8Copy(s, i, 1);
    case ch of
      'А', 'Б', 'В':
      begin
        UTF8Delete(s, i, 1); UTF8Insert(UTF8LowerCase(ch), s, i);
      end;
    end;
  end;
  Edit1.Text := s;
end;



1



2 / 2 / 1

Регистрация: 23.04.2015

Сообщений: 56

25.03.2016, 21:51

 [ТС]

11

Благодарю вас хороший человек



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

25.03.2016, 21:51

Помогаю со студенческими работами здесь

Перевод букв из прописных в строчные
Всем добрый день! Задача вроде бы проста — есть исходный файл. Получить второй файл образованный из…

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

Получить файл g, образованный из файла f заменой всех его прописных (больших) букв на строчные (малые)
Дан текстовый файл f. Получить файл g, образованный из файла f заменой всех
его прописных…

Подсчитать, сколько было введено: латинских прописных букв, кириллических прописных букв, цифр, знаков переноса, прочих символов.
Помогите, пожалуйста, написать программу :scratch:
Подсчитать, сколько было введено: латинских…

Подсчёт количества прописных и строчных букв и преобразование строки
Надо подсчитать в строке количество прописных и строчных букв и преобразовать строку соответственно…

Преобразование заглавных букв в строчные
Доброго времени суток! Есть программа на TASM, преобразовывающая маленькие буквы в большие. Прошу…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

11

Понравилась статья? Поделить с друзьями:
  • Error inaction number 1of create eventfor object objdevolver error defining an external function
  • Error inaccessible boot device
  • Error in writing the output log при загрузке что делать
  • Error in wifi password text with at least 8 and maximum 64 symbols expected mikrotik
  • Error in vbios image rx 5700