程序不断返回 Segmentation Fault
Program keeps returning Segmentation Fault
我是一个喜欢玩编码的新人。最近我正在学习一个关于 edx 的课程,我需要完成的练习之一有这个小代码片段,它不断地给出分段错误。我已经删除了错误的部分(其他一切都编译得很好)
#include <stdio.h>
#include <string.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
if (argc == 2 && isalpha(argv[1]))
{
int a = 0;
while (argv[1][a] == '[=10=]')
{
a++;
printf("%c\n", argv[1][a]);
}
}
else
{
printf("Usage: ./programname 1-alphabetical word\n");
return 1;
}
}
问题似乎出在这里:argv[1][a]
但我终究无法找出是什么以及如何解决它。
isalpha(argv[1])
看起来不正确,应该是 isalpha(argv[1][0])
isalpha 需要一个字符,但您在函数中输入了一个字符串
另一件突出的错误是 argv[1][a] == '[=13=]'
==
应该是 !=
这意味着 while 循环一旦到达 [=16=]
就会停止
也许
if (argc == 2)
{
int a = 0;
while (argv[1][a] != '[=10=]')
{
if (isalpha(argv[1][a])
printf("%c\n", argv[1][a]);
a++;
}
}
可能是您要找的东西?
(1) isalpha(argv[1])
是错误的。该函数需要一个字符,但您传递的是一个指向字符串的指针。这肯定不会给您任何预期的结果,而且很可能 Undefined Behaviour 成为交易的一部分。您需要循环并检查每个字符,使用更高级的库函数来检查整个字符串,或者 - 作为快速且可能改变意义的修复 - 只需按照 BLUEPIXY 的建议检查第一个字符:isalpha( argv[1][0] )
或 isalpha( *argv[0] )
.
(2) 您的 while
条件错误。你告诉它循环 而 当前字符是 NUL
。这将对非空字符串不执行任何操作,并针对空字符串解决下一个问题 #3。您大概是指 while (argv[1][a] != '[=16=]')
,即只循环直到达到 NUL
字节。
(3) 在尝试 printf()
之前增加索引 a
。如果输入字符串为空,这将立即索引超出范围,因为主体执行,然后您立即索引超出终止 NUL
。即使循环条件是固定的,您也会错过第一个字符,然后打印终止符 NUL
,这两者都没有意义。您应该只在确认 a
在范围内并完成您需要对其进行的操作后才增加。所以,printf()
它,然后增加它。
2 和 3 似乎最容易通过使用 for
循环而不是手动拆分循环变量的初始化、测试和递增来解决。您还应该使用正确的索引类型:如果您想要打印包含数百万或数十亿个字符的字符串,int
不够宽,而且它不是好的样式。所以:
#include <stddef.h> /* size_t */
for (size_t a = 0; argv[1][a] != '[=10=]'; ++a) {
printf("%c\n", argv[1][a]);
}
我看到的分段错误的唯一原因是 if 语句的这个子表达式
if (argc == 2 && isalpha(argv[1]))
^^^^^^^^^^^^^^^^
指定的参数类型不正确。表达式 argv[1]
的类型为 char *
而该函数需要一个字符类型的对象,该对象被解释为 unsigned char
并提升为类型 int
.
因此,当提升的参数具有负值(EOF 值除外)时,函数 isalpha
具有未定义的行为。
来自 C 标准(7.4 字符处理 <ctype.h>
)
1 The header <ctype.h>
declares several functions useful for
classifying and mapping characters.198) In all cases the argument is
an int, the value of which shall be representable as an unsigned
char or shall equal the value of the macro EOF. If the argument has
any other value, the behavior is undefined.
你应该像这样写 if 语句
if (argc == 2 && isalpha( ( unsigned char )argv[1][0] ) )
或喜欢
if (argc == 2 && isalpha( ( unsigned char )*argv[1] ) )
while 语句中还有一个错误,如果参数不是空字符串,它永远不会执行。我想你的意思如下
int a = 0;
while ( argv[1][a] != '[=13=]' )
{
printf("%c\n", argv[1][a]);
a++;
}
或者例如喜欢
int a = 0;
while ( argv[1][a] )
{
printf("%c\n", argv[1][a++]);
}
我是一个喜欢玩编码的新人。最近我正在学习一个关于 edx 的课程,我需要完成的练习之一有这个小代码片段,它不断地给出分段错误。我已经删除了错误的部分(其他一切都编译得很好)
#include <stdio.h>
#include <string.h>
#include <cs50.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
if (argc == 2 && isalpha(argv[1]))
{
int a = 0;
while (argv[1][a] == '[=10=]')
{
a++;
printf("%c\n", argv[1][a]);
}
}
else
{
printf("Usage: ./programname 1-alphabetical word\n");
return 1;
}
}
问题似乎出在这里:argv[1][a]
但我终究无法找出是什么以及如何解决它。
isalpha(argv[1])
看起来不正确,应该是 isalpha(argv[1][0])
isalpha 需要一个字符,但您在函数中输入了一个字符串
另一件突出的错误是 argv[1][a] == '[=13=]'
==
应该是 !=
这意味着 while 循环一旦到达 [=16=]
也许
if (argc == 2)
{
int a = 0;
while (argv[1][a] != '[=10=]')
{
if (isalpha(argv[1][a])
printf("%c\n", argv[1][a]);
a++;
}
}
可能是您要找的东西?
(1) isalpha(argv[1])
是错误的。该函数需要一个字符,但您传递的是一个指向字符串的指针。这肯定不会给您任何预期的结果,而且很可能 Undefined Behaviour 成为交易的一部分。您需要循环并检查每个字符,使用更高级的库函数来检查整个字符串,或者 - 作为快速且可能改变意义的修复 - 只需按照 BLUEPIXY 的建议检查第一个字符:isalpha( argv[1][0] )
或 isalpha( *argv[0] )
.
(2) 您的 while
条件错误。你告诉它循环 而 当前字符是 NUL
。这将对非空字符串不执行任何操作,并针对空字符串解决下一个问题 #3。您大概是指 while (argv[1][a] != '[=16=]')
,即只循环直到达到 NUL
字节。
(3) 在尝试 printf()
之前增加索引 a
。如果输入字符串为空,这将立即索引超出范围,因为主体执行,然后您立即索引超出终止 NUL
。即使循环条件是固定的,您也会错过第一个字符,然后打印终止符 NUL
,这两者都没有意义。您应该只在确认 a
在范围内并完成您需要对其进行的操作后才增加。所以,printf()
它,然后增加它。
2 和 3 似乎最容易通过使用 for
循环而不是手动拆分循环变量的初始化、测试和递增来解决。您还应该使用正确的索引类型:如果您想要打印包含数百万或数十亿个字符的字符串,int
不够宽,而且它不是好的样式。所以:
#include <stddef.h> /* size_t */
for (size_t a = 0; argv[1][a] != '[=10=]'; ++a) {
printf("%c\n", argv[1][a]);
}
我看到的分段错误的唯一原因是 if 语句的这个子表达式
if (argc == 2 && isalpha(argv[1]))
^^^^^^^^^^^^^^^^
指定的参数类型不正确。表达式 argv[1]
的类型为 char *
而该函数需要一个字符类型的对象,该对象被解释为 unsigned char
并提升为类型 int
.
因此,当提升的参数具有负值(EOF 值除外)时,函数 isalpha
具有未定义的行为。
来自 C 标准(7.4 字符处理 <ctype.h>
)
1 The header
<ctype.h>
declares several functions useful for classifying and mapping characters.198) In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behavior is undefined.
你应该像这样写 if 语句
if (argc == 2 && isalpha( ( unsigned char )argv[1][0] ) )
或喜欢
if (argc == 2 && isalpha( ( unsigned char )*argv[1] ) )
while 语句中还有一个错误,如果参数不是空字符串,它永远不会执行。我想你的意思如下
int a = 0;
while ( argv[1][a] != '[=13=]' )
{
printf("%c\n", argv[1][a]);
a++;
}
或者例如喜欢
int a = 0;
while ( argv[1][a] )
{
printf("%c\n", argv[1][a++]);
}