2013-11-13 7 views
2

Я пытаюсь просто выскочить каждое числовое значение и добавить их вместе, чтобы получить общее количество.Выпадающие клавиши массива для вычисления общего количества

входного файла:

Samsung 46 
RIM  16 
Apple  87 
Microsoft 30 

Мой код компилируется ... он возвращает только 0, хотя.

open (UNITS, 'units.txt') || die "Can't open it $!"; 
my @lines = <UNITS>; 
my $total = 0; 
while (<UNITS>) { 
    chomp; 
    my $line = pop @lines; 
    $line += $total; 
} 
print $total; 
+3

'моя = @ строка,' читают все строки файла, не оставляя ни для 'в то время как ()' читать. Тогда есть проблема, что 'pop @ lines' не имеет смысла. Вы хотите последнее поле строки, а не последнюю строку. – ikegami

+0

, возможно, вы хотите сказать (@lines), но pop @lines возвращает всю строку, которая оценивается в 0, поэтому вы добавляете 0 к сумме. Вам нужно разобрать каждую строку для этого номера – Davs

+0

@Davs: вы должны представить это как ответ – Borodin

ответ

5

Нет необходимости хлебать все строки в массив, если вы только собираетесь перебрать их так или иначе с while. Кроме того, вам нужно указать split каждую строку, чтобы получить ваши номера.

use warnings; 
use strict; 

open (UNITS, 'units.txt') || die "Can't open it $!"; 
my $total = 0; 
while (<UNITS>) { 
    chomp; 
    my $num = (split)[1]; 
    $total += $num; 
} 
print "$total\n"; 

__END__ 

179 
+0

Мне нравится (split) [1], что поможет с некоторыми проблемами, с которыми я столкнулся. Благодаря! – Nicktard

+2

'(split) [- 1]' может быть лучше предположить, так как первый столбец состоит из имен компаний, и весьма вероятно, что он может содержать пробелы. – Borodin

+0

@Nicktard: если вы имеете дело только с одним полем каждой записи, гораздо лучше извлечь * все * поля, используя 'my @fields = split', а затем выбрать нужные вам данные (в этом случае' $ fields [1] '). Также обратите внимание на мой предыдущий комментарий: если у вас есть пробелы в любой из ваших данных, то голый 'split' будет делить отдельные поля на несколько. – Borodin

2
use strict; 
use warnings; 
open my $fh, "<", "units.txt" or die "well..."; 

my $total = 0; 
while(<$fh>){ 
chomp; 
my ($string, $num) = split(" ", $_); 
$total += $num; 
} 
print $total; 
+3

Ваш код неплохой, но отличные ответы также объясняют, почему они так поступают. Не могли бы вы добавить несколько объяснений и, возможно, правильно откорректировать код? – amon

5

Есть три проблемы здесь

  • Вы пытаетесь добавить строки, как 'Samsung 46' + 'RIM 16'

  • Читает весь файл в @lines, а затем попытаться прочитать больше из файл в цикле while. Этот цикл никогда не вводится, потому что вы уже прочитали до конца файла

  • Вы добавляете $total к (необъявленной) переменной $line в пределах цикла, а не наоборот. Так $total остается на нуле и $line сохраняет с нулём к нему добавляется

Лучше использовать while для чтения файлов, если вам нужно что-то другое, чем последовательный доступ к записям, поэтому удаление @lines начало.

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

Вы должны всегдаuse strict и use warnings в начале каждой программы. Это мера, которая облегчит поиск ошибок в вашем коде. Также лучше использовать лексические файлы, а не глобальные, и трехпараметрическую форму open.

use strict; 
use warnings; 

open my $units, '<', 'units.txt' or die "Can't open it: $!"; 

my $total; 

while (<$units>) { 
    my @fields = split; 
    $total += $fields[-1]; 
} 
print $total; 

выход

179 
0

Эта проблема является пустяком с однострочника:

$ perl -ane '$sum += $F[1] }{ print $sum' units.txt 

Объяснение

  • -a позволяет AutoSplit, каждая строка split и хранятся в @F
  • -n петель через файл построчно
  • -e говорит perl, что следующий аргумент должен рассматриваться как код Perl
  • левой части эскимосский поцелуй (этот смешной вид }{ посередине) выполняется для каждой строки во входном файле, RHS выполняется только один раз
  • LHS накапливает второй столбец каждой строки в $sum
  • RHS выводит результат $sum, когда все линии были обработаны
Смежные вопросы