Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> меняем print местами и не работает, может кто знает почему? 
:(
    Опции темы
dpush
Дата 1.12.2008, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 1.12.2008

Репутация: нет
Всего: нет



есть файл, в нем:
1    1    serv1
2    1    serv2
3    1    serv3
4    2    serv4
5    2    serv5
6    3    serv6

написал код, и случайно заметил что:
Код

    while ($line=<FILE>){        
        chomp $line;                
        foreach (split(/[ ]+|\t+/, $line)){                        
            print ":";
            print $_;
        }
        print "\n";
    }

и второй вариант
Код

    while ($line=<FILE>){        
        chomp $line;         
        foreach (split(/[ ]+|\t+/, $line)){                        
            print $_;            
            print ":";
        }
        print "\n";
    }

первый аутпут(все как и хотели):
perl test.pl -f service.txt
:1:1:serv1
:2:1:serv2
:3:1:serv3
:4:2:serv4
:5:2:serv5
:6:3:serv6


второй (ууупс):
perl test.pl -f service.txt
::1:serv1
::1:serv2
::1:serv3
::2:serv4
::2:serv5
::3:serv6


почему от перемены мест принта совершенно неожиданный вывод????


Это сообщение отредактировал(а) dpush - 1.12.2008, 15:33
PM MAIL   Вверх
amg
Дата 1.12.2008, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Вообще-то Ваш код ничего не должен напечатать(за исключением ругани на неоткрытый filehandle FILE при включенных предупреждениях). Но если заменить <FILE> на <>, то все нормально. 

ЗЫ Почему бы не заменить /[ ]+|\t+/ на ' ' или хотя бы на /\s+/
ЗЫЗЫ А опция -f с какой целью?
PM MAIL   Вверх
dpush
Дата 1.12.2008, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 1.12.2008

Репутация: нет
Всего: нет



это часть кодаsmile , а не код целиком... весь не интересен, интересен тока это момент.
через -f  я файл передаю...
PM MAIL   Вверх
amg
Дата 1.12.2008, 16:25 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Ух, сообразил, как такой эффект мог получиться. Дело в неправильных концах строк: каждая строка кончается на "\r\n" (DOS-формат), а исполнение скрипта, видимо, происходит на *nix (ну или файл был открыт в бинарной моде). Дальше, думаю, понятно: после того как напечаталось serv1, происходит возврат каретки ("\r"), и двоеточие печатается на месте 1-го символа.

Бороться с этим просто: вместо Вашего регулярного выражения для split используйте ' ' (пробел в кавычках).

Добавлено через 2 минуты и 34 секунды
Цитата(dpush @  1.12.2008,  16:20 Найти цитируемый пост)
через -f  я файл передаю.

dpush, опция -f в перле отнюдь не для передачи файла, не используйте ее, если точно не знаете, что она нужна.
PM MAIL   Вверх
amg
Дата 1.12.2008, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



dpush, позволю себе привести немного более краткий, но аналогичный Вашему код:
Код
while (<>) {
   foreach (split){                        
       print $_;
       print ":";
   }
   print "\n";
}

Вызывать 
perl test.pl service.txt

PM MAIL   Вверх
dpush
Дата 1.12.2008, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 1.12.2008

Репутация: нет
Всего: нет



спаибо! похоже на правду!

а про -f -а почему нет? я использую Getopt.. ключ -f относится не к perl а к test.pl .... (> ./test.pl -f file.txt)

Добавлено через 1 минуту и 49 секунд
ща подумал, а разве chomp не должен отрезать концы строк?

Добавлено через 11 минут и 48 секунд
хм, помогло вот это:
Код

chomp $line;
chop $line;

криворуко, да?

всегда думал что chomp достаточно...

Добавлено через 12 минут и 55 секунд
chop - не опечатка, действительно есть такая функция)))
PM MAIL   Вверх
dpush
Дата 1.12.2008, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 1.12.2008

Репутация: нет
Всего: нет



оказывается - проблема решена)

спасибо amg Ваша идея с концами строк в разных осах, и есть правильный ответ!

Это сообщение отредактировал(а) dpush - 1.12.2008, 17:33
PM MAIL   Вверх
tolkien
Дата 2.12.2008, 01:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 277
Регистрация: 5.4.2008

Репутация: 4
Всего: 4



вобще для удаления перехода на новою строку еще используют такой вариант
s/[\r\n]+$//;
PM MAIL   Вверх
amg
Дата 2.12.2008, 07:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



dpush, С -f все нормально, это я не туда посмотрел по невнимательности. Конечно же, у Вас это опция не перла, а скрипта.

chomp $line;
chop $line;

Это неудачное решение. Если файл будет с правильными концами строк, то результат будет неправильным -- chop удалит последний символ строки. Лучше вместо Вашего регулярного выражения для split используйте ' ' (пробел в кавычках), тогда ни chop, ни chomp не нужет будет (хотя chomp и не помешает). К тому же, у Вашего регулярного выражения для split есть еще один недостаток: если в качества разделителя полей окажется комбинация идужих подряд пробелов и табуляторов, то получится неожиданный результат.  

Другое решение -- вместо chomp используйте вариант tolkien: $line =~ s/[\r\n]+$//;
PM MAIL   Вверх
amg
Дата 2.12.2008, 07:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(dpush @  1.12.2008,  17:32 Найти цитируемый пост)
оказывается - проблема решена)
Да это и не проблема то вовсе. Только на этом форуме вопрос о неправильных концах строк и как с этим бороться вставал раз этак двести. Кстати, то что предлагают по приведенной Вами ссылке (устанавливать значение $/ = "\r\n") -- тоже не самое хорошее, т.к. не универсальное решение. Сегодня у Вас файл с непривильными концами строк (например, передали его по FTP, забыв включить ascii-моду), а завтра -- с правильными, chomp ничего не удаляет и скрипт начинает глючить. Универсальные решения предложены выше.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0478 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.