IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Задача на сортировку стрингов., Мое решение некорректно работает с кириллицей :(
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 8
Пол: Мужской

Репутация: -  0  +


Итак, суть задачи: дан файл input.txt, содержащий в первой строке число - количество строк, а затем строку в каждой строке. Необходимо отсортировать эти строки в порядке убывания, при этом создав файл config.txt вида
Код
1 1 1

//Первое число показывает, стоит урезать пробелы или нет.
Если надо обрезать пробелы, ставим 1. Если не надо, 0.
Пример:
При сравнении строк "А Б В" и " АБВ" со значением опции 1 в выходной файл будут выведены
строки "АБВ" и "АБВ", со значением опции 0 - " АБВ" и "А Б В" соответственно.

//Второе число показывает, считать большие буквы равные маленьким, или нет.
Если считать большие буквы равные маленьким, ставим 1. Если считать их разными, 0.
Пример:
При сравнении строк "абв" и "АБВ" со значением опции 1 в выходной файл будут выведены "АБВ"
и "АБВ". При значении опции 0 - "АБВ" и "абв" соответственно.

//Третье число показывает, транслитерировать русские названия или нет.
Если надо транслитерировать русские названия, все кириллические символы будут переведены в
символы латиницы. Если нет, то русские символы останутся на месте, а все русские строки
в выходном файле будут расположены после латинских.
Пример:
При сравнении строк "zak" и "абв" при значении опции 1 в выходной файл будут выведены "abv"
и "zak", при значении опции 0 - "zak" и "абв" соответственно.


Результат должен быть выведен в файл output.txt

Моя программа (все текстовые файлы и исходник программы) добавлена в прикрепления.

Вот код основной программы:


program strsort;
var f1,f2,conf:text;
n:integer;
a:array[1..1000] of string;
i,k,e,q:integer;
r:integer;
s,s1,s2,t:string;
opt1,opt2,opt3:integer;
function trlit(a:string):string;
var s:string;
q:string;
t,k:integer;
begin
q:='';
s:='';
k:=1;
t:=length(a);
while k<=t do begin
case a[k] of
... (тут все буквы большого и малого регистра кириллицы и их аналоги в транслите)
else s:=a[k];
end;
if length(s)>=2 then begin t:=t+length(s); k:=k+length(s); end;
q:=q+s;
k:=k+1;
end;
trlit:=q;
end;
function up(s:string):string;
var stmp:string;
z:byte;
c:char;
begin
stmp:='';
for z:=1 to length(s) do
begin
c:=s[z];
case c of
'а'..'п':stmp:=stmp+chr(ord©-32);
'р'..'я':stmp:=stmp+chr(ord©-80);
else stmp:=stmp+upcase©;
end;
end;
up:=stmp;
end;
function sravn(s1,s2:char):integer;
begin
if s1<s2 then sravn:=1;
if s1=s2 then sravn:=0;
if s1>s2 then sravn:=2;
end;
function probel(s:string):string;
var i,l:integer;
begin
l:=length(s); 
for k:=1 to l do for i:=1 to l do if s[i]=' ' then begin delete(s,i,1); l:=l-1; end;
probel:=s;
end;
begin
assign(f1,'input.txt');
assign(f2,'output.txt');
assign(conf,'config.txt');
reset(conf);
read(conf,opt1,opt2,opt3);
close(conf);
if ((opt1<>0) and (opt1<>1)) or ((opt2<>0) and (opt2<>1)) or ((opt3<>0) and (opt3<>1)) then
begin
writeln('Ошибка при чтении конфигурационных данных.');
writeln('Поломался файл config.txt ');
readln;
halt;
end;
reset(f1);
readln(f1,n);
for i:=1 to n do readln(f1,a[i]);
close(f1);
if opt1=1 then for i:=1 to n do a[i]:=probel(a[i]);
if opt2=1 then for i:=1 to n do a[i]:=up(a[i]);
if opt3=1 then for i:=1 to n do a[i]:=trlit(a[i]);
k:=1;
while k<n do begin
for i:=1 to n-1 do begin
r:=0; q:=1;
while r=0 do begin
s1:=a[i];
s2:=a[i+1];
r:=sravn(s1[q],s2[q]);
if (q>length(s1)) or (q>length(s2)) then r:=1;
q:=q+1;
end;
if r=2 then begin s:=a[i]; a[i]:=a[i+1]; a[i+1]:=s; end;
end;
k:=k+1;
end;
rewrite(f2);
for i:=1 to n do writeln(f2,a[i]);
close(f2);
end.



Программа компилируется и абсолютно корректно работает со строками в латинице и кириллице с отключенными опциями 2 (перевод с верхний регистр) и 3 (транслитерация). С включенными опциями 2 и 3 программа с кириллицей работает некорректно. Если я правильно понимаю, скомпиленная ФриПаскалем прога не может корректно работать с виндовскими текстовыми файлами, и поэтому считывает кириллицу некорректно. Подскажите, пожалуйста, что делать, и как научить прогу полностью корректно обращаться с кириллицей.
Спасибо.

Сообщение отредактировано: forscripts -


Прикрепленные файлы
Прикрепленный файл  StringSort.rar ( 2.49 килобайт ) Кол-во скачиваний: 102
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Судя по функции up - приведение к верхнему регистру - она ориентирована на 866 кодовую страницу (используемую в DOS), и даже для нее неверно обрабатывает букву "ё". В виндах обычно испольуется 1251 кодовая страница (в GUI, и 866 - в консоли). Неплохо бы предусмотреть в программе переключение между кодировками - в Виндах может понадобиться и та, и другая.

По поводу работы с кодировками.
Рекомендую воспользоваться чем-то вроде:
var
i,j,k : integer;
f : file;
begin
assign(f,'ascii.cod');
rewrite(f,1);
for j := 0 to 15 do begin
for i := 0 to 15 do begin
k := i + j*16;
blockwrite(f,k,1);
end;
k := 13;
blockwrite(f,k,1);
k := 10;
blockwrite(f,k,1);
end;
close(f);
end.

Полученный таким образом файл можно прсматривать в различных кодирвках встроенными во вьюеры Total Commander'а или FAR'а для выявления закономерностей перекодирования.
Могу сразу сказать, что для ВСЕХ символов нижнего регистра (включая "ё") в 1251 от их кода надо отнимать 32. Только диапазоны будут несколько другими.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






forscripts, для начала разберись с компилятором. Если ты используешь FPC (а то, что ты не пользуешься TP - это однозначно, у меня нет дефектов зрения, присущих другим), то используй и AnsiUpperCase/AnsiLowerCase для перевода в нужный регистр. При правильном использовании они работают с любой кодовой страницей.

А вообще вопрос надо бы передвинуть... В 32-бита...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Цитата(volvo @ 15.12.2007 17:43) *
А вообще вопрос надо бы передвинуть... В 32-бита...
А зачем?
Неужели 1000 строк следует обрабатывать другим алгоритмом, нежели 200?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5





Группа: Пользователи
Сообщений: 8
Пол: Мужской

Репутация: -  0  +


andriano, спасибо за помощь, попробую так...
Я пробовал и тупо отнимать 32 от численного значения символа в кириллице (методом проб и ошибок определил, под какими номерами стоят буквы кириллицы), но все равно не работало корректно(((
volvo апкейс не работает корректно, к сожалению, тоже. Юзаю ФПК, да.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Так надо отнимать не от ЛЮБОГО символа кириллицы, а только от СТРОЧНОГО.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7





Группа: Пользователи
Сообщений: 8
Пол: Мужской

Репутация: -  0  +


я понял, просто неправильно выразился))
все равно корректно не работало.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гуру
*****

Группа: Пользователи
Сообщений: 1 168
Пол: Мужской
Реальное имя: Сергей Андрианов

Репутация: -  28  +


Да, для ё и некоторых букв украинского/белорусского алфавита отнимать надо 16.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 22.10.2021 1:59
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name