编写电话号码程序时出现段错误
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
我正在编写一个 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