2013-09-25 3 views
0

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

strcmp возвращает разность значений ascii первых непревзойденных символов. i.e strcmp («hello», «world») - -15, а strcmp («привет», «Hello») - 32. Надеюсь, вы это получили.

+0

должны быть конкретными по требованию. «Точно так же, как' strcmp' в C », вы хотите, чтобы он возвращал' -1', если string1 string2? – lurker

+0

strcmp возвращает разницу в символах ascii. i.e strcmp («hello», «world») - -15, а strcmp («привет», «Hello») - 32. Надеюсь, вы получили его – rocker

+0

Очевидно, мы все смущены тем, что вы пытаетесь сделать. Отправьте пример ввода и ожидаемый результат, чтобы помочь нам помочь вам. –

ответ

3

Вы можете получить разницу между значениями ASCii двух символов, как это:

(($(printf %d \"$a) - $(printf %d \"$b)) 

Так это должно работать:

strcmp() { 
    local diff 
    for ((i=0; i<=${#1}; ++i)); do 
    if ((diff=$(printf %d \""${1:i:1}") - $(printf %d \""${2:i:1}"))); 
     then echo $diff; return 
    fi 
    done 
    echo 0 
} 

Вы не указали, что значение должно быть, если один строка является префиксом другого; в приведенном выше примере используется конечный символ NUL (0) более короткой строки для вычисления разности.

Тестирование:

$ strcmp hello world 
-15 
$ strcmp hello Hello 
32 
$ strcmp abc def 
-3 
$ strcmp def abc 
3 
$ strcmp def dbc 
3 
$ strcmp def ddc 
1 
$ strcmp def dgc 
-2 
$ strcmp def dec 
3 
$ strcmp def de 
102 
$ strcmp de def 
-102 
$ strcmp def def 
0 
$ strcmp "a b c" "a bde" 
-68 
$ strcmp "a b c" "a b e" 
-2 
+0

Я понял это вчера.Anyways It отлично работает :) – rocker

0

Howabout

$ diff <(echo "stackoverflow") <(echo "stackowerflow") 
1c1 
< stackoverflow 
--- 
> stackowerflow 

или

$ cmp -bl <(echo "stackoverflow") <(echo "stackowerflow") 
        7 166 v 167 w 

Или, петля над всеми символами в строке:

#!/bin/bash 

foo=string 
for ((i=0; i<${#foo}; i++)); do 
    echo ${foo:$i:1} 
done 

выход:

s 
t 
r 
i 
n 
g 
+0

как получить ascii разницу первых непревзойденных символов от этого. Выход diff неясен. Cmp возвращает ascii где-то в своем выходе. Я думаю, что что-то нужно сделать на этом выходе – rocker

1

Используйте test (здесь называемый в скобках), чтобы сделать лексическое сравнение.

[ 'bar' '<' 'foo' ] # returns true 
[ 'bar' '>' 'foo' ] # returns false 
[ 'bar' = 'foo' ] # returns false 

Вы можете собрать небольшую функцию, которая несколько подражает strcmp функции C в:

function strcmp { 
    if [ $1 == $2 ] 
    then 
     return 0 
    elif [ $1 '<' $2 ] 
    then 
     return 2 
    fi 
    return 1 
} 

strcmp foo bar 
echo $? 

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

+0

Need ascii difference not true или false. Hope Im clear – rocker

+0

Извините, не осознавал этого, пока не прочитал ваши комментарии. Первоначально 'strcmp' определяет только то, является ли число равным, больше или меньше нуля, точное значение определяется реализацией. –

+0

Я запускаю свой код C с помощью gcc, он показывает разницу ascii. – rocker

0

Некоторые неприятные люди говорят, что PHP не что иное, как обертка вокруг C, так что давайте использовать, что: установлен

$ difference=$(php -r "echo strcmp('foo', 'far');") 
$ echo $difference 
14 

PHP на большинстве систем или могут быть легко добавлены. Не определено, что возвращаемые значения strcmp должны быть чем угодно, но равными, меньше или больше 1 - чтобы код не считался переносимым без дальнейшего тестирования (например, при запуске PHP, скомпилированном с другими компиляторами, чем gcc).

+0

php не найден, что он показывает для меня. И я предполагаю, что он использует стандартный strcmp внутри. Любой другой способ? – rocker

+0

Затем установите его, не должно быть больше одной строки и несколько секунд на Linux-системах. ;) Если нет, вы должны написать все сами. –

+0

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

1

В Баш (так как вы помечать его):

$ cat tst.sh 
function strcmp() { 
    printf "%d\n" $(($(printf "%d" "'${1:0:1}") - $(printf "%d" "'${2:0:1}"))) 
} 

printf "strcmp(\"$1\",\"$2\") = %d\n" $(strcmp "$1" "$2") 
$ ./tst.sh foo foo 
strcmp("foo","foo") = 0 
$ ./tst.sh foo bar 
strcmp("foo","bar") = 4 
$ ./tst.sh bar foo 
strcmp("bar","foo") = -4 
+1

Это также возвращает '0' для' foo' и 'far' (хотя строки не равны), тогда как функция' strcmp', которую он говорит, что он использует, вернет значение ''o '-' a''. – lurker

+0

Darn it! Я не собираюсь тратить время на это, но OP может кодировать сравнение char-by-char, если ему нравится использовать вышеупомянутый метод для получения числовых значений символов. –

+0

В любом случае я написал правильный код, используя только printf. Просто хотел что-то вернуть Ascii Value. printf сделал трюк :) – rocker

1

Следующая функция дос работы,

strcmp() 
    { 
    arg1=$1 
    len=${#arg1} 
    arg2=$2 
    len1=${#arg2} 
    len1=$(($len1+1)) 
    len=$(($len+1)) 
    i=0 
    # echo $len - $len1 

    while [ $i -le $len ] || [ $i -le $len1 ]; 
    do 
     tem1=${arg1:$i:1} 
     tem2=${arg2:$i:1} 
     # echo $tem1-$tem2; 
     val1=`echo $tem1 | tr -d "\n" | od -An -t dC`  
     val2=`echo $tem2 | tr -d "\n" | od -An -t dC` 
     res=$(($val1-$val2)) 
     if [ $res -lt 0 ] ; then 
     # echo "Less $res" 
      break 
     elif [ $res -gt 0 ] ; then 
      #echo "Greater $res" 
      break 
     # else 
     #  echo "Equal" 
     fi 
     i=$(($i+1)) 
     # echo "i=$i" 
    done 
    echo $res 
    } 






echo $(strcmp "Zefaop" "Zefat") 
Смежные вопросы