2011-10-16 2 views
0

Я хочу рассчитать частоту появления символов в сообщении с помощью Perl. Например, если символ «a» появляется в сообщении 10 раз, тогда частота будет равна 10. Чтобы сделать это, я читаю сообщение с одного элемента FILE за один раз, используя функцию getc. Вот фрагмент, который я написал. Я знаю, это очень просто. Но когда я компилирую, я получаю сообщение об ошибке:Почему моя программа с использованием функции getc Perl работает неправильно?

Детали:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $input=$ARGV[0]; 

open(INPUT,"<$input"); 

while(<INPUT> 
{ 
my $c=getc(INPUT); 
print $c."\n"; 
} 

close(INPUT); 

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

Use of uninitialized value in print at AccessChar.pl line 13, <INPUT> line 1.

Я не в состоянии фигуры вне, что не так с этим скриптом. Может ли кто-нибудь помочь мне с этим?

Я даже попытался использовать getc INPUT вместо getc(INPUT). Я не думаю, что мне нужно включать любые другие пакеты во время запуска этого скрипта.

+4

У вас есть синтаксическая ошибка в этом фрагменте (в строке 'while'). – Mat

+1

'getc' не работает ... О, да, это так. –

ответ

2

Mixing файл чтения (оператор) <...> с getc это плохая идея. Это не так, как вы думаете.

Попробуйте добавить в программу некоторый отладочный вывод, чтобы узнать, что происходит. Я протестировал программу, запустив ее самостоятельно (./getc getc).

В начале цикла while<INPUT> читает строку из вашего файла и сохраняет ее в $_. Затем вы используете getc, чтобы прочитать следующий символ из файла. Это будет первый символ из второй строки вашего файла (вероятно, символ новой строки, который, вероятно, будет единственным символом в этой строке).

В следующий раз по кругу, <INPUT> читает следующую строку ввода. Это линия use strict. getc читает следующий символ, который является «u» от use warnings.

И так продолжается до конца файла. <INPUT> читает строку, а затем getc считывает первый символ из следующей строки.

Это совсем не то, что вы хотите. Если вы хотите читать персонажа за раз, вам просто нужен getc.

#!/usr/bin/perl 

use strict; 
use warnings; 

my $input = shift; 

open(my $file, '<', $input); 

while (defined(my $c = getc $file)) { 
    print "$c\n"; 
} 

Другой альтернативой было бы просто использовать <...> и разделить каждую строку, как вы читаете это.

#!/usr/bin/perl 

use strict; 
use warnings; 

my $input = shift; 

open(my $file, '<', $input); 

while (<$file>) { 
    foreach my $c (split //) { 
    print "$c\n"; 
    } 
} 

Но смешивание двух подходов никогда не сработает.

5
while (<INPUT>) 

будет читать всю строку из INPUT на каждой итерации цикла. Если вы хотите обработать этот файл, обрабатывая один символ за раз, это неправильная конструкция для использования.

Попробуйте что-то вроде:

my $c; 
while (defined($c = getc(INPUT))) { 
    print $c, "\n"; 
} 
+0

Спасибо! Это работает :) Мне нравится ваша идея. Поскольку getc возвращает значение undef в Error или EOF, мы можем использовать определенную функцию. Интересно! –

1

Просто для маленькой TIMTOWTDI:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Data::Dumper; 

local $/; 
my %chars; 

$chars{$_}++ for split //, <>; 

print Dumper \%chars; 

, который работает до тех пор, пока файл не слишком велик, чтобы чавкать; если это чтение и разделение каждой строки. Использование:

$ count_chars.pl file_to_read 

 Смежные вопросы

  • Нет связанных вопросов^_^