программа выводит на 1 больше фактического количества элементов в массиве - PullRequest
0 голосов
/ 22 марта 2020

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

#!/bin/bash

i=0
declare -a arr
line="buffer"
while [ -n "$line" ]
do
    read line
    arr[$i]="$line"
    i=`expr $i + 1 `
done
for i in ${arr[@]}
do
    echo "element $i"
done
echo ${#arr[@]}

контрольный пример

Nauru
Nepal
Netherlands
NewZealand
Nicaragua
Niger
Nigeria
NorthKorea
Norway

вывод

element Nauru
element Nepal
element Netherlands
element NewZealand
element Nicaragua
element Niger
element Nigeria
element NorthKorea
element Norway
10

Ожидаемый результат

element Nauru
element Nepal
element Netherlands
element NewZealand
element Nicaragua
element Niger
element Nigeria
element NorthKorea
element Norway
9

Ответы [ 3 ]

1 голос
/ 22 марта 2020

Что сказали другие ответы. Это ошибка забора . Обратите внимание, что bash предлагает несколько ярлыков для таких заданий. С помощью этих ярлыков вся программа может быть уменьшена до:

mapfile -t arr < data
printf 'element %s\n' "${arr[@]}"
echo "${#arr[@]}"

Преимущество заключается в меньшем количестве путаницы в переменных, mapfile выполняет инициализацию и не имеет циклов.

0 голосов
/ 22 марта 2020

Когда read line выдает пустое значение line, вы все равно добавляете его в массив перед проверкой необходимости выхода из l oop.

Когда вы выполняете итерацию по массиву расширение параметра без кавычек отбрасывает пустой конечный элемент; цитируя его (for i in "${arr[@]}"), вы получите

element Nauru
element Nepal
element Netherlands
element NewZealand
element Nicaragua
element Niger
element Nigeria
element NorthKorea
element Norway
element 
10

Сначала проверьте значение, при необходимости изменив его, , затем обновите массив.

declare -a arr
while read line
do
    arr+=("$line")
done
for i in "${arr[@]}"
do
    echo "element $i"
done
echo "${#arr[@]}"
0 голосов
/ 22 марта 2020

Как вы выходите из while l oop? Вы делаете это, вводя пустую строку (просто нажимая Return). Что ж, l oop не прерывается мгновенно, , но помещает пустую строку в следующий элемент массива и увеличивает значение i (что, впрочем, используется ни для чего).

Итак, в общем, длина массива всегда будет на один больше ожидаемой. Если все еще не ясно, рассмотрите это:

$ a=()
$ echo ${#a[@]}
0
$ a[0]=         #Assigns empty string
$ echo ${#a[@]}
1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...