编写电话号码程序时出现段错误

Segmentation fault at writing the telephone number program

我正在编写一个 C 程序,提示用户以 (xxx)xxx-xxxx 的形式输入电话 phone 号码,然后以 xxx.xxx.xxxx 的格式显示号码。这是一个例子:

Enter a phone number [(xxx) xxx-xxxx]: (404)817-6200
You entered the data 404.817.6200

我创建了两个字符串,一个用于存储带有括号和“-”符号的 phone 数字,另一个为空。我想将每个字符添加到空字符串中,将 ')' 和 '-' 更改为 '.'。这是我的代码:

#include <stdio.h>
int main(void){
    char num[15];
    char phone[13];

    int i = 1;
    int j = 0;
    printf("Please, enter your phone number in the format (xxx)xxx-xxxx:");
    scanf("\n%s", num);
    while(num != '[=11=]'){
        if(num[i] == ')' || num[i] == '-'){
            phone[j] = '.';
        }else{
            phone[j] = num[i];
        }
        i++;
        j++;
        
    }
    printf("\n%s",phone);
}

当我 运行 程序时,它给我的错误消息是:

Segmentation fault

有人可以解释为什么会发生这种情况以及将来如何预防吗?

我在你的程序中发现了三个问题:

(1) while(num != '[=11=]') 应该是 while(num[i] != '[=12=]'num 是一个数组(并且永远不会比较等于 '[=14=]',所以你会得到一个无限循环并超出数组边界。

(2) phone 至少需要 14 个字节(只比 num 少一个,不能少两个)

(3) 需要在phone中写入一个字符串终止符;否则 printf("\n%s",phone); 将再次超出 phone 的界限;例如:

}
phone[j] = '[=10=]';
printf("\n%s",phone);`

当您在 C 中引用数组变量的名称时,如果不附加 [](索引)运算符,您是(有效地)引用 地址该数组的第一个元素。对于声明为局部变量的数组,这永远不会为零(或 NULL),因此 while 循环中 num 与零('[=16=]')的比较将 永远不会为真,循环将运行一直持续,直到您尝试读取或写入无效地址,此时程序将崩溃。

启用编译器警告后,您应该会看到如下内容(由 clang-cl 生成):

warning : comparing a pointer to a null character constant; did you mean to compare to NULL? [-Wpointer-compare]
warning : comparison of array 'num' not equal to a null pointer is always true [-Wtautological-pointer-compare]

您应该做的是比较 'current' 元素(在索引 i 处)与 nul 字符('[=16=]')以检查字符串结尾:

    while (num[i] != '[=10=]') {// Check character at position "i"
        // rest of your loop ...

您还应该确保您的 phone 字符串正确地 nul 终止(尽管一些编译器会将数组初始化为零,但不要依赖于此)。您可以通过在 phone:

的声明中添加初始化程序来做到这一点
    char phone[13] = { 0 }; // Will set all elements to zero

或在 while 循环结束后立即添加 nul 终止符

        // body of while loop
        // ...
    }
    phone[j] = '[=12=]'; // Append the terminator