1

I am new to C. I am experienced in GWBASIC. In an effort to learn, I am attempting to write a program that will convert the individual chars in a string to a numerical value as so:

1 2 3 4 5 6 7 8 9
a b c d e f g h i
j k l m n o p q r
s t u v w x y z

For example, user input for string A could be 'dog', said program would then store [d][o][g] as [4][6][7] in string B. The below code works for a string w/up to four chars, but there must be a more efficient way of doing this.

int main()
{
    char a[0];
    char b[0];
    scanf("%s",a);
    if (a[0] == 'a' || a[0] == 'j' || a[0] == 's') b[0] = '1';
    if (a[0] == 'b' || a[0] == 'k' || a[0] == 't') b[0] = '2';
    if (a[0] == 'c' || a[0] == 'l' || a[0] == 'u') b[0] = '3';
    if (a[0] == 'd' || a[0] == 'm' || a[0] == 'v') b[0] = '4';
    if (a[0] == 'e' || a[0] == 'n' || a[0] == 'w') b[0] = '5';
    if (a[0] == 'f' || a[0] == 'o' || a[0] == 'x') b[0] = '6';
    if (a[0] == 'g' || a[0] == 'p' || a[0] == 'y') b[0] = '7';
    if (a[0] == 'h' || a[0] == 'q' || a[0] == 'z') b[0] = '8';
    if (a[0] == 'i' || a[0] == 'r') b[0] = '9';
    if (a[1] == 'a' || a[1] == 'j' || a[1] == 's') b[1] = '1'; 
    if (a[1] == 'b' || a[1] == 'k' || a[1] == 't') b[1] = '2';
    if (a[1] == 'c' || a[1] == 'l' || a[1] == 'u') b[1] = '3';
    if (a[1] == 'd' || a[1] == 'm' || a[1] == 'v') b[1] = '4';
    if (a[1] == 'e' || a[1] == 'n' || a[1] == 'w') b[1] = '5';
    if (a[1] == 'f' || a[1] == 'o' || a[1] == 'x') b[1] = '6';
    if (a[1] == 'g' || a[1] == 'p' || a[1] == 'y') b[1] = '7';
    if (a[1] == 'h' || a[1] == 'q' || a[1] == 'z') b[1] = '8';
    if (a[1] == 'i' || a[1] == 'r') b[1] = '9';
    if (a[2] == 'a' || a[2] == 'j' || a[2] == 's') b[2] = '1';
    if (a[2] == 'b' || a[2] == 'k' || a[2] == 't') b[2] = '2';
    if (a[2] == 'c' || a[2] == 'l' || a[2] == 'u') b[2] = '3';
    if (a[2] == 'd' || a[2] == 'm' || a[2] == 'v') b[2] = '4';
    if (a[2] == 'e' || a[2] == 'n' || a[2] == 'w') b[2] = '5';
    if (a[2] == 'f' || a[2] == 'o' || a[2] == 'x') b[2] = '6';
    if (a[2] == 'g' || a[2] == 'p' || a[2] == 'y') b[2] = '7';
    if (a[2] == 'h' || a[2] == 'q' || a[2] == 'z') b[2] = '8';
    if (a[2] == 'i' || a[2] == 'r') b[2] = '9';
    if (a[3] == 'a' || a[3] == 'j' || a[3] == 's') b[3] = '1';
    if (a[3] == 'b' || a[3] == 'k' || a[3] == 't') b[3] = '2';
    if (a[3] == 'c' || a[3] == 'l' || a[3] == 'u') b[3] = '3';
    if (a[3] == 'd' || a[3] == 'm' || a[3] == 'v') b[3] = '4';
    if (a[3] == 'e' || a[3] == 'n' || a[3] == 'w') b[3] = '5';
    if (a[3] == 'f' || a[3] == 'o' || a[3] == 'x') b[3] = '6';
    if (a[3] == 'g' || a[3] == 'p' || a[3] == 'y') b[3] = '7';
    if (a[3] == 'h' || a[3] == 'q' || a[3] == 'z') b[3] = '8';
    if (a[3] == 'i' || a[3] == 'r') b[3] = '9';
    printf("%s\n",b);
    return 0;
}
5
  • note that in C the '=' operator is assignment, to check equality use the == operator. You could something like if(strA[0] == 'a' || strA[0] == 'j' || strA[0] == 's') strB[0] = 1; ... and so on for the other cases, to check this for every character use a for or while loop and instead of the 0 use an incremented value. Commented Nov 30, 2011 at 21:20
  • @rankep: I think that salicemspiritus wants strB[0] = '1' rather than strB[0] = 1. Commented Nov 30, 2011 at 21:23
  • Also, to check if a value is equal to a character, you have to put the character within apostropges: if (strA[0] == 'a') Commented Nov 30, 2011 at 21:25
  • There's no such thing as an array of 0 length; you need char a[1]. Commented Nov 30, 2011 at 23:55
  • @ruakh yes you are absolutely right, this happens when I'm in a hurry, and just try to leave a quick comment. Commented Dec 1, 2011 at 7:40

6 Answers 6

6

Assuming that your compiler uses an ASCII encoding then you can use the following simple arithmetic to get your answer:

1 + (strA[i] - 'a') % 9

You really don't want to implement this with a long list of if statements or indeed a switch statement.

Naturally you will have input validation issues if you have non alphabetical characters, numeric characters, upper-case characters and so on. I presume you can simply ignore those for a learning exercise.

Sign up to request clarification or add additional context in comments.

5 Comments

Just a side note: Based on the chart provided, I believe the OP would then have to %9 this value.
@williamg my guess is that chart needs to be corrected!! ;-)
I would have thought so too, but in his comment he used the columns 1-9 regardless of the row. However, I have a bad habit of assuming things... ;-)
@DavidHeffernan: seeing how 'o' gets converted to '6', I think the OP means to use only 1-9.
Thank you, but I am unsure of how to apply this.
2

To correct your original approach, you need to do two things:

  • Use single quotes around character constants;
  • Use == to check for equality;
  • Terminate statements with ;.

... so your snippet becomes:

if (strA[0] == 'a')
    strB[0] = '1';
if (strA[0] == 'b')
    strB[0] = '2';
if (strA[0] == 'c')
    strB[0] = '3';

Comments

2

You can type the following exactly into a gwbasic editor and it will solve your problem

10 INPUT A$

12 L = LEN(A$)

15 FOR T = 1 TO L

20 M$ = MID$(A$,T,1)

25 GOSUB 70

30 B$ = B$ + V$

35 NEXT T

40 PRINT B$

50 END

55 REM -----------------

70 REM - Subroutine to convert m$ into v$

72 X = ASC(M$) : REM this is the ascii value of m$ (eg. "a" = 97)

74 X = X - 96 : REM so that 97 becomes "1"

80 IF X > 9 THEN X = X - 9 : GOTO 80

90 V$ = STR$(X) : REM just converting to a string type variable

95 RETURN : REM takes you back to line 30 where this value is added to the

96 REM final resulting B$ - when I say added I mean a char added to a string

97 REM such that   "APPL" + "E" = "APPLE"

98 REM ------------------------------------------ DONE

Comments

1

For ASCII, it would go somewhat like:

... make sure strB has enough space ...
for (i = 0; i < ... length of strA ... ; i++) {
    /* you should always check your input is valid */
    if (strA[i] >= 'a' && strB[i] <= 'z')
        strB[i] = (strA[i] - 'a') % 9 + 1;
    else
        strB[i] = ... some default value ...
}

For EBCDIC:

for (i = 0; i < ... length of strA ... ; i++) {
    /* you should always check your input is valid */
    if (strA[i] >= 'a' && strB[i] <= 'r')
        strB[i] = strA[i] & 0xF;
    else if (strA[i] >= 's' && strB <= 'z')
        strB[i] = (strA[i] & 0xF) - 1;
    else
        strB[i] = ... some default value ...
}

5 Comments

@DavidHeffernan: heh, nice and EBCDIC in the same sentence, who would have thought?
@salice yes you do. But that's very basic C and unrelated to the question you asked.
@David Thank you for all your help. I am still unable to apply what you have said. I apologize for being a novice, I am doing my best to learn.
Try to use the suggestions that ninjalj and I have made. The key is to use 1 + (strA[i] - 'a') % 9 instead of your if statements. Write a complete program that way and then if that does not work ask a new question containing that complete program. Then we can help. But do not persist in writing it out in if statements and do not use copy/paste as a primary development tool.
This will be my goal tonight. Thank you very much for your help; you are a good person.
0

Have a closer look at an ASCII table. You'll see that all letters are encoded with some integer value. As a start, if you only have lower case letters, it's enough to substract the character code of 'a' from any letter to get what you want

int nr = strA[0] - 'a' + 1;
//now you'd need to convert back to a string; better: strB should be an array of integer

Also, = is the assignment operator; you need to use == to check for equality.

Comments

0

try this :)

int strB[MAX_LEN] = {0};
char *strA = malloc (MAX_LEN * sizeof(char));
int i,c = 0,x;

scanf("%s",strA);

for(i = 0 ; i<strlen(strA) ; i++){
    x = strA[i] - 'a' + 1;
    if(x >= 1 && x <= 9)
        strB[c] = x;
    else if(x <= 18){
        strB[c] = x - 10;
    else if(x <= 26){
        strB[c] = x - 19;
    if(x <= 26)
        c++;
}

or you can use ninjalj approach in the for loop, if you aleady checked the input:

for(i=0 ; i<strlen(strA) ; i++){
    strB[i] = (strA[i] - 'a') % 9 + 1;
}

or this :

for(i=0 ; i<strlen(strA) ; i++){
    if(strA[i] >= 'a' && strA[i] <= 'z'){
        strB[c] = (strA[i] - 'a') % 9 + 1;
        c++;
    }
}

1 Comment

why are you dynamically allocating strA, if strB is statically allocated?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.