我正在编写一个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
有人可以解释为什么会发生这种情况以及将来如何预防吗?
答案 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