tags:

views:

164

answers:

6

I'm trying to solve the problem here but I don't know why my code isn't working. Any help is appreciated. EDIT: Edited to make correction mentioned below, but there is still an extra "15" (in bold) on the second line of the output and I don't understand where it is coming from.

My output is

18662658515 555227215

#include <stdlib.h>
#include <stdio.h>

int main(void){
  int n;
  int j;
  scanf("%d\n", &n);
  int i = 0;
  char mystr[15];

  for(;i<n;i++){
    fgets(mystr,15,stdin);

    for(j=0;j<15;j++){
      if(isdigit(mystr[j])){
        printf("%c", mystr[j]);
        continue;
      }
      if ('A' <= mystr[j] && mystr[j] <= 'C')
        printf("2");
      if ('D' <= mystr[j] && mystr[j] <= 'F')
        printf("3");
      if ('G' <= mystr[j] && mystr[j] <= 'I')
        printf("4");
      if ('J' <= mystr[j] && mystr[j] <= 'L')
        printf("5");
      if ('M' <= mystr[j] && mystr[j] <= 'O')
        printf("6");
      if ('P' <= mystr[j] && mystr[j] <= 'S')
        printf("7");
      if ('T' <= mystr[j] && mystr[j] <= 'V')
        printf("8");
      if ('W' <= mystr[j] && mystr[j] <= 'Z')
        printf("9");
    }
    printf("\n");
  }
}
+6  A: 

For one thing, I think your comparisons are backwards. For example, you should be testing "if ('A' <= mystr[j] && mystr[j] <= 'C')".

Fred Larson
Yup; if you're going to use the backwards comparison notation, you need to use the consistent notation.
Jonathan Leffler
+1  A: 

consider that you might want to compare things in the same order. Speak this out in plain english before writing code. If myLetterCode is Greater Than A.code && myLetterCode is Less than C.Code (it must be B!).

keep your letter on the left and the thing you're comparing it to on the right. Otherwise it gets very confusing very fast.

Dr.Dredel
A: 

I think there's a bug with the SO markup. The preview of

18662658515 5552272**15**

doesn't match what is actually displayed. On the preview the "15" is highlighted in bold, but after posting you can see the asterisks.

Stu
I fixed it by replacing the **** tags with <b> and </b>. A very strange case!
e.James
Thanks. I guess I'll file a bug.
Stu
+2  A: 

It would be helpful, perhaps, to have a function between() (with apologies; my C is rusty):

bool between(char c, char before, char after) {
    return before <= c && c <= after;
}

so

if ('A' <= mystr[j] && mystr[j] <= 'C')
        printf("2");

becomes

if (between(mystr[j], 'A', 'C')
        printf("2");

It is generally better to use half-open ranges, where the lower limit is inclusive and the upper limit exclusive. With this, then, the last element of each test would be the first element of the preceding test, which could help you detect certain kinds of bugs more readily.

Carl Manaster
+3  A: 

The problem is that you're iterating over all 15 characters in the input string, regardless of the length of the input. The first test case has 11 characters, but the second case has only 8. In the second iteration, you're accidentally processing the last two characters from the first input, which were 15.

To fix it, just stop your iteration when you hit the NUL character 0, which terminates the string by changing this line

for(j=0;j<15;j++){

to

for(j=0; mystr[j] != 0; j++){
Adam Rosenfield
Thanks. I can see why people don't like writing in C :(
Stu
+1  A: 

Wouldn't this be easier with a lookup table?

int numbers[] = {              2, 2, 2,  3, 3, 3,
                     4, 4, 4,  5, 5, 5,  6, 6, 6,
                  7, 7, 7, 7,  8, 8, 8,  9, 9, 9, 9};

... cut ...

if (isdigit (mystr[j]))
    printf ("%c", mystr[j]);
else
    printf ("%d", numbers[mystr[j] - 'A']);

... cut ...
dreamlax
That is a cleaner way but I was not clever enough to think of it.
Stu