2015-02-12 2 views
-4

Я новичок в C, и я работал над этой домашней проблемой около 2 часов безрезультатно. Я пытаюсь создать программу, которая принимает буквенный номер телефона (например, CALLATT или 1-800-COL-LECT) и превращает его в цифровую форму (2255288 или 1-800-265-5328). Независимо от того, что я поставил для ввода, я всегда получаю -4197680 для моего вывода.Почему моя программа C выдает тот же результат независимо от того, что я положил для ввода?

int main(void){ 

    int c=0, len, a[len]; 
    char n[len]; 

    printf("Enter phone number: \n"); 
    scanf("%c", n); 

    len = sizeof(n)/sizeof(n[0]); 

    while (len > c){ 
     if (n[c] == 'A' || n[c] == 'B' || n[c] == 'C'){ 
      a[c] = 2;  
      c++; 
     } 
     else if (n[c] == 'D' || n[c] == 'E' || n[c] == 'F'){ 
      a[c] = 3;  
      c++; 
     } 
     else if (n[c] == 'G' || n[c] == 'H' || n[c] == 'I'){ 
      a[c] = 4;  
      c++; 
     } 
     else if (n[c] == 'J' || n[c] == 'L' || n[c] == 'L'){ 
      a[c] = 5;  
      c++; 
     } 
     else if (n[c] == 'M' || n[c] == 'N' || n[c] == 'O'){ 
      a[c] = 6;  
      c++; 
     } 
     else if (n[c] == 'P' || n[c] == 'Q' || n[c] == 'R' || n[c] == 'S'){ 
      a[c] = 7;  
      c++; 
     } 
     else if (n[c] == 'T' || n[c] == 'U' || n[c] == 'V'){ 
      a[c] = 8;  
      c++; 
     } 
     else if (n[c] == 'W' || n[c] == 'X' || n[c] == 'Y' || n[c] == 'Z'){ 
      a[c] = 9;  
      c++; 
     } 
     else { 
      a[c] = n[c]; 
      c++; 
     }   
    } 

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

    return 0; 
} 
+0

и не должно быть 'scanf ("% s ", & n)'? –

+3

Я вижу UB здесь. 'int a, len, a [len];' --- 'len' не инициализируется в точке, где он используется для' a' (и 'n' в следующей строке). Также обратите внимание, что это использует довольно слабо поддерживаемую функцию C99 (хотя по крайней мере GCC и CLang поддерживают ее просто отлично). –

+1

@AlvaroMontoro: Нет. 'Scanf' берет указатель на начало буфера, а не указатель на указатель (нет необходимости, поскольку он не выделяет никакой памяти сам по себе). –

ответ

3

EDIT: пересмотренный. Было много комментариев, указывающих на проблемы, вот мой ответ, который работает с разумным номером телефона. Он пропускает любые символы без набора номера, такие как '-', который не является частью номера телефона.

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

int main(void){ 
    int k, d, e, len; 
    char dial[20], entry[20] = {0}; 
    printf("Enter phone number: "); 
    fgets(entry, 19, stdin); 
    len = strlen(entry); 
    d = 0;         // dial string index of output 
    for (e=0; e<len; e++) {    // entry string index of input 
     k = entry[e]; 
     switch (toupper(k)) { 
      case 'A': case 'B': case 'C':   dial[d++] = '2'; break; 
      case 'D': case 'E': case 'F':   dial[d++] = '3'; break; 
      case 'G': case 'H': case 'I':   dial[d++] = '4'; break; 
      case 'J': case 'K': case 'L':   dial[d++] = '5'; break; 
      case 'M': case 'N': case 'O':   dial[d++] = '6'; break; 
      case 'P': case 'Q': case 'R': case 'S': dial[d++] = '7'; break; 
      case 'T': case 'U': case 'V':   dial[d++] = '8'; break; 
      case 'W': case 'X': case 'Y': case 'Z': dial[d++] = '9'; break; 
      default: 
       if (isdigit(k) || k=='*' || k=='#') dial[d++] = k; 
     } 
    } 
    dial[d] = 0;   // terminate string 
    printf("Dial %s\n", dial); 
    return 0; 
} 
+0

Ничего себе, спасибо большое!Кажется, что использование переключателя вместо цикла while работает намного лучше. – MoreFoam

0

Вот код:

char buf[32]; 
sscanf("%31s", buf); 

size_t i; 

for (i = 0; i < sizeof(buf) && buf[i]; ++i) 
{ 
switch (buf[i]) 
{ 
case 'A': case 'B': case 'C': 
    buf[i] = '2'; break; // Note: character literal, not integer 
case 'D': case 'E': case 'F': 
    buf[i] = '3'; break; 
.... 
} 
} 
printf("%s", buf); 

Если у вас есть Posix-совместимая библиотека, вы можете использовать динамическое распределение:

char *buf; 
scanf("%ms", &buf); //scanf would allocate memory 

for (i = 0; buf[i]; ++i) 
{ 
..... 
} 

printf("%s", buf); 
free(buf); 
+0

@MattMcNabb. Вы правы. Ty. –

0

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

Вот скелетная программа, которая захватывает эти три шага.

#define SIZE 50 

void readPhoneNumber(char phoneNumber[]) 
{ 
} 

void convertTextToNumber(char phoneNumber[], char dialedNumber[]) 
{ 
} 

void printPhoneNumber(char phoneNumber[]) 
{ 
} 

int main(void) 
{ 
    char phoneNumber[SIZE]; 
    char dialedNumber[SIZE]; 

    readPhoneNumber(phoneNumber); 

    convertTextToNumber(phoneNumber, dialedNumber); 

    printPhoneNumber(dialedNumber); 
} 

Теперь вы можете начать выполнять функции. Например, readPhoneNumber может быть реализован как:

void readPhoneNumber(char phoneNumber[]) 
{ 
    printf("Enter phone number: \n"); 
    fgets(phoneNumber, SIZE, stdin); 
} 

printPhoneNumber могут быть реализованы в виде:

void printPhoneNumber(char phoneNumber[]) 
{ 
    printf("%s\n", phoneNumber); 
} 

Я оставлю вас, чтобы отработать реализацию convertTextToNumber.

0

Здесь у вас есть неопределенное поведение, len не инициализируется.

int c=0, len, a[len]; 
char n[len]; 

Вместо этого используйте вместо этого постоянное значение, я ставлю, что номер телефона в вашей стране имеет некоторую максимальную длину.


Этот способ чтения с клавиатуры, не рекомендуется, зсапЕ не проверяет длину строки, так что вы можете сделать faceroll на клавиатуре и программа зависнет. Вместо того, чтобы использовать fgets() для чтения из стандартного ввода затем пройти через строку полукокс по полукоксу пропуска включены \n

printf("Enter phone number: \n"); 
scanf("%c", n); 

Это не имеет никакого смысла, рассчитать SizeOf п т.е. целого числа, который содержит п. Если вы хотите, чтобы длина строки использовала strlen (n); btw попробуйте использовать более описательные имена переменных.

len = sizeof(n)/sizeof(n[0]); 

Вместо

while (len > c){ 

почему бы не использовать обычный для цикла? вы, кажется, увеличиваете C++ везде.


это здесь не будет делать то, что вы ожидаете, что делать

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

но вы назначаете «а» целые числа, например,

a[c] = 2; 

printf не может магически печатать ряд вашего массива, вместо этого вы хотите распечатать строку с цифрами. значение ascii цифры равно 48 + цифра. например «0» равно 48, зная, что это имеет буфер символов и добавляет к нему значения ascii. убедитесь, что он заканчивается на \ 0, который является концом строки. затем распечатайте строку

buf[c++] = 48 + digit; 
... 
buf[c] = '\0'; 
puts(buf); 
Смежные вопросы