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

时间:2020-10-14 20:21:10

标签: c string segmentation-fault scanf

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

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

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

#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 != '\0'){
        if(num[i] == ')' || num[i] == '-'){
            phone[j] = '.';
        }else{
            phone[j] = num[i];
        }
        i++;
        j++;
        
    }
    printf("\n%s",phone);
}

运行程序时,它会显示以下错误消息:

Segmentation fault

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

2 个答案:

答案 0 :(得分:0)

我在您的程序中看到了三个问题:

(1)while(num != '\0')应该是while(num[i] != '\0'num是一个数组(永远不会比较等于'\0',因此您将得到一个无限循环并超出数组范围。

(2)phone至少需要14个字节(比num少1个字节,不比2个少

(3)您需要将字符串终止字符写入phone;否则printf("\n%s",phone);将再次超出phone的范围;例如:

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

答案 1 :(得分:0)

在C语言中引用数组变量的名称时,没有附加[](索引)运算符,(有效地)引用了该数组第一个元素的 address 。对于声明为局部变量的数组,该值永远不会为零(或NULL),因此num循环中的'\0'与零(while)的比较将< em>从不为真,并且循环将不间断地运行,直到您尝试读取或写入无效地址为止,此时程序将崩溃。

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

警告:将指针与空字符常量进行比较;你是否 意味着要比较NULL? [-Wpointer-compare]
警告:比较 数组“ num”不等于空指针始终为true [-Wtautologic-pointer-compare]

您应该做的是将“当前”元素(在索引i处)与nul字符('\0')进行比较,以检查字符串的结尾:

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

您还应该确保phone字符串正确地以nul结尾(尽管某些编译器会将数组初始化为零,但不要依赖于此)。您可以通过在phone的声明中添加一个初始化器来实现此目的:

    char phone[13] = { 0 }; // Will set all elements to zero

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

        // body of while loop
        // ...
    }
    phone[j] = '\0'; // Append the terminator
相关问题