• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

[solved] Alphabet

catweasel

Hacker
Hi!

Gibt es eine (elegante) Möglichkeit, ausgehend von einem Buchstaben den x-nächsten zu bestimmen?

z.B.:

a +3 =d
f +1 =g
 
Code:
alphabet="abcdefghijklmnopqrstuvwxyz";
read buchstabe;
read zahl;
str="${alphabet%%$buchstabe*}";
str="${#str}";
str=$[($str + $zahl) % ${#alphabet}];
str="${alphabet:$str:1}";
echo "Zielbuchstabe ist $str";
Jetz klar? :p
 
OP
C

catweasel

Hacker
jengelh schrieb:
Code:
perl -e 'print ++($_="a")'

perl kann ich nicht, aber ich denke den zweiten Code hab ich verstanden.

abgdf schrieb:
http://tldp.org/LDP/abs/html/wrapper.html#PRASC

da ich auch etwas für die andere Richtung brauche, habe ich gesucht und bin dabei auf diese Seite gestoßen:

http://www.dbforums.com/archive/index.php/t-584958.html

Das habe ich mir damit zusammengebaut (ohne alles genau verstanden zu haben, z.B. das mit den zwei printf)
Code:
buchstabe=c
zahl=2
printf "\\$(printf %o $(($(echo $buchstabe | od -An -N1 -tu1) + $zahl)))\n"

ist kürzer als jengelhs zweiter Code :p
 
Hmm, als alter shell-Fan hätte ich etwas was für Kleinbuchstaben geht. Geht in Bash. Bei ksh müsste man noch portierarbeit ( -e entfernen ?) leisten.

Code:
buchstabe=a
zahl=1
echo -e "\\0$((((26#$buchstabe+87+$zahl)/64)*100+((26#$buchstabe+87+$zahl)/8%8)*10+((26#$buchstabe+87+$zahl)%8)))"

Alles verständlich ? *grins*

Haveaniceday
 
Manchmal hilft eine Nacht drüber schlafen.
So sieht es als "pure shell" kürzer aus:

buchstabe=a
zahl=1
echo -e "\\0`printf %o $((26#$buchstabe+87+$zahl))`"
Und für Grossbuchstaben:
echo -e "\\0`printf %o $((26#$buchstabe+55+$zahl))`"

:)

Edit: OOps, Überlauf. Basis 26 ist zu gering. ( geht nur für Buchstaben bis p, da "a" schon für dezimal 10 steht. )

Basis 36 ist OK:
echo -e "\\0`printf %o $((36#$buchstabe+87+$zahl))`"
Und für Grossbuchstaben:
echo -e "\\0`printf %o $((36#$buchstabe+55+$zahl))`"


Edit "value => ascii"
Code:
pascii()
{
printf %b "\\0$(printf %o $(($1%256)))"
}

pascii 0107
pascii 71
pascii 0x47
Geht leider mit Octal nicht unter ksh... Aber unter bash geht es.
 

abgdf

Guru
Hi,

da anscheinend ein griffiges Unix-Tool dafür fehlt, würde ich ausnahmsweise tatsächlich mal C einsetzen:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* printasc.c
   Compile with: gcc -Wall -pedantic -o printasc printasc.c */

int checkDigits(char *a);

int main(int argc, char *argv[])
{
    int a;

    if(argc == 1 || argc > 2)
    {
        puts("Not enough or too many arguments.");
        return 1;
    }

    if (checkDigits(argv[1]) != 0)
    {
        puts("Argument must be a number.");
        return 2;
    }

    a = atoi(argv[1]);

    if (a < -255 || a > 255)
    {
        puts("The argument is either too big or too small.");
        return 3;
    }

    printf("%c\n", a);

    return 0;
}


int checkDigits(char *a)
{
    int i;
    for(i = 0; i < strlen(a); i++)
    {
        if (*(a + i) < '0' || *(a + i) > '9')
        {
            if (*a != '-')
            {
                return 1;
            }
        }
    }
    return 0;
}

Viele Grüße
 
Na das kann man aber auch besser fassen (Stichwort atoi-- strtol++) Außerdem weiß ich nicht wieso du auf "a < -255" testest...
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
    char *err;
    unsigned int a;

    if(argc != 2) {
        puts("Not enough or too many arguments.");
        return 1;
    }

    a = strtoul(argv[1], &err, 0);
    if (err != NULL && *err != '\0') {
        puts("Argument must be a number.");
        return 2;
    }

    if (a > 255) {
        puts("The argument is either too big or too small.");
        return 3;
    }

    printf("%c\n", a);
    return 0;
}
 

abgdf

Guru
Hallo,

meinen C-Code kann man immer besser fassen. Das sagen jedenfalls alle, denen ich ihn zeige. Das ist mir egal, solange er - einigermaßen schnell - läuft und keine Speicherlecks verursacht.
Wegen dieser andauernden Diskussionen verwende ich grundsätzlich auch lieber Python. Denn da gilt:
"There should be one -- and preferably only one -- obvious way to do it."
http://www.python.org/doc/Humor.html#zen
Außerdem weiß ich nicht wieso du auf "a < -255" testest...
Deutsche Sonderzeichen sind als "signed char" negativ. Unterhalb von -255 sollten keine mehr sein.

Gruß
 
Ich sehe aber nirgends dein "signed char". Du verwendest stattdessen ein int. %c nimmt auch einen int (weil char hochpromoted wird), und versteht nebst 0..255 auch -1..-128. Aber generell gibt es bei "char" kein Vorzeichen oder ein Vorzeichen - es "interessiert keinen", "char" ist praktisch ein von "signed char" und "unsigned char" unterschiedlicher Typ. Linus hat dazu einen langen Thread... Naja printf("%c %c\n", -1, 255) tun jedenfalls dasselbe FWIW. (Aber wenn schon, dann -128 <= x <= 127, und nicht -255 <= x <= 255 8) ) Und anzunehmen, deutsche Sonderzeichen wären ausgerechnet negativ - naja, statistisch vielleicht wahr, aber das muss ja nicht überall gelten. Womit wir auch bei Unicode wären, da kommt man mit a={128..255} nicht weit, weil eine unvollständige Sequenz ausgegeben würde. Das könnte man natürlich mithilfe von iconv wieder wett machen...
 
ksh/bash hat eine Arithmetik die über "let a=1+2" oder über "$((a=1+2)" angesprochen werden kann.
Da kann man Bitoperationen, etc. machen und z.B. mit anderen Zahlensystemen rechnen.
10#8 ist z.B. die Zahl Acht im Dezimalsystem.
16#F ist im Hexadezimalsystem das "0xF" als dezimal die 15.

Deine Buchstabenaufgabe kann man auch als Zahlenaufgabe im "36er" Zahlensystem sehen.
1=> 1
...
9=> 9
a=> 10
b=> 11
..
z=> 35
Durch 36#$buchstabe wird also z zu 35. Und da lässt sich dann "Zahl" einfach dazu zählen.

87(+10 aus <system>#<zahl/buchstabe> wegen dem a) ist der "ASCII-Wert" von einem 'a' ( siehe man ascii )
=> $((36#$buchstabe+87+$zahl)) ist also der ASCII-wert
von dem Ergebnis. printf %o "ergebnis" gibt den Wert oktal aus.

Und "echo -e \0<oktalzahl>" gibt dann das passende Zeichen aus.
 
OP
C

catweasel

Hacker
Thx!

das macht Spaß :lol:
echo $((2#11101001001010100001010001))
geht das andersherum auch?
# echo $((42 ? 2)) = 101010

als Nichtmathematiker frage ich mich: ist das einfach so, dass hier nach 9 mit "a" als 10 weitergezählt wird?

Gibt es keine Möglichkeit, direkt den dezimalen Wert der ascii-Tabelle in Buchstaben umzuwandeln?
 
Oben