【问题标题】:Convert phone number from alphabetic to numeric form将电话号码从字母形式转换为数字形式
【发布时间】:2019-03-07 14:20:19
【问题描述】:

我正在做 KNKings 书籍“C 编程:一种现代方法”中的练习,其中涉及将用户输入的字母形式的电话号码转换为数字形式。当程序遇到非字母字符(例如数字或标点符号)时,应该保持它们不变。我可以假设用户只输入大写字母。

但是,至少可以说,我的程序似乎产生了垃圾。

#include <stdio.h>

#define MAX_SIZE 50

int main(void)
{
    char alphabetic[MAX_SIZE], ch;
    int num_elements = 0;

    printf("Enter phone number: ");
    int i;
    for (i = 0; i < MAX_SIZE && ((ch = getchar()) != '\n'); i++){
        alphabetic[i] = ch;
        num_elements++;
    }

    for (i = 0; i <= num_elements; i++){
        switch (alphabetic[i]){
            case 'A': case 'B': case 'C': alphabetic[i] = '2'; break;
            case 'D': case 'E': case 'F': alphabetic[i] = '3'; break;
            case 'G': case 'H': case 'I': alphabetic[i] = '4'; break;
            case 'J': case 'K': case 'L': alphabetic[i] = '5'; break;
            case 'M': case 'N': case 'O': alphabetic[i] = '6'; break;
            case 'P': case 'R': case 'S': alphabetic[i] = '7'; break;
            case 'T': case 'U': case 'V': alphabetic[i] = '8'; break;
            case 'W': case 'X': case 'Y': alphabetic[i] = '9'; break;
            default:                                           break;
        }
    }
    printf("%s\n", alphabetic);
    return 0;
}

我特别输入:COLLECT-800。 它输出如下内容:u░@■   ║k ╩

我做错了什么?

【问题讨论】:

  • ch 应该是 int
  • @Lundin 你能解释一下原因吗?
  • @Shuster 与您的问题无关,但您缺少 QZ 案例。
  • @Shuster 因为 getchar 返回一个 int 而 EOF 是一个 int。
  • @GovindParmar 好点,我不知道。但我不确定你对“最近”的定义是否准确,我的第一部手机(20 年前左右)已经有了 Q 和 Z ;-)

标签: c arrays character


【解决方案1】:

您的想法是正确的,但您的程序中缺少两件事:

  1. 最重要的是,字符串末尾的空终止符。在您读取数字的for 循环之后,添加以下行:

    alphabetic[i] = '\0';
    
  2. 如果用户输入小写字母,它们将在 switch 语句中被忽略。要解决此问题,请包含 &lt;ctype.h&gt; 并将 switch 数量从 alphabetic[i] 更改为 toupper(alphabetic[i])。在已经大写的字母上调用 toupper 是良性的。

【讨论】:

  • 首先感谢您的帮助,但是有什么办法可以确保程序读完字符后自动添加空终止符?
  • @Shuster 要实现这一点,您应该使用一种实际上用于读取字符串而不是来自stdin 的单个字符(即getchar)的方法; fgets 是个不错的选择。
【解决方案2】:

您没有在任何地方放置空终止符,因此当您读取字符串时,无论您之后是否修改它,它都是未定义的行为。把这一行:

alphabetic[num_elements] = 0;

在您的for (i = 0; i &lt; MAX_SIZE &amp;&amp;... 循环之后。


就个人而言,我不会执行getchar 循环,而是像这样读取字符串:

scanf("%49s", alphabetic); // reads in a string up to 50 characters
for (i = 0; alphabetic[i]; i++) { ...

【讨论】:

  • 这不太正确。输入格式说明符 's' 总是在输入后面附加一个 NUL 字节,所以语句应该是:scanf("%49s", alphabetic);