程序不断返回分段错误

时间:2017-07-28 12:08:33

标签: c string while-loop cs50 isalpha

我是一个喜欢玩编码的新人。最近我正在阅读关于edx的课程,我需要完成的一个练习有这个小代码片段,它不断给出Segmentation故障。我已经拿出了错误的一点(其他一切编译得很好)

#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] == '\0')
        {
            a++;
            printf("%c\n", argv[1][a]);
        }
    }
    else
    {
        printf("Usage: ./programname 1-alphabetical word\n");
        return 1;
    }
}

问题似乎在这里:argv[1][a]但我不能为我的生活找到什么,以及如何解决它。

3 个答案:

答案 0 :(得分:0)

isalpha(argv[1])看起来不正确,应该是isalpha(argv[1][0])

isalpha接受一个字符,但您输入了一个字符串函数

错误的另一件事是argv[1][a] == '\0' == !=  应为\0这意味着while循环会在点击if (argc == 2) { int a = 0; while (argv[1][a] != '\0') { if (isalpha(argv[1][a]) printf("%c\n", argv[1][a]); a++; } } 后停止

也许

<table style="width:100%;" border="1">
  <tr>
    <td style="">
      <div style="width:10%; min-width:100px; max-width:200px; width:auto;">
        The text goes here
      </div>
    </td>
    <td style="">
      <input style="width:10%; min-width:100px; max-width:200px; width:auto;" 
             type="text" value="field is here">
    </td>
    <td style="width:80%;"></td>
  </tr>
</table>

可能正是您要找的?

答案 1 :(得分:0)

(1)isalpha(argv[1])错了。此函数需要单个字符,但您传递的是指向字符串的指针。这肯定不会给你任何预期的结果,它可能是未定义的行为进入讨价还价。您需要循环并检查每个字符,使用更高级别的库函数来检查整个字符串,或者 - 作为一个快速且可能有意义的修改 - 只需检查第一个字符为BLUEPIXY建议:isalpha( argv[1][0] )isalpha( *argv[0] )

(2)您的while条件错误。您告诉它循环,而当前字符为NUL。对于非空字符串,这不会做任何事情,并且对于空字符串会遇到下一个问题#3。您可能意味着while (argv[1][a] != '\0'),即仅在到达NUL字节之前循环。

(3)在尝试a之前增加索引printf()。如果输入字符串为空,当主体执行时,这将立即索引超出范围,然后您立即索引超出终止NUL。即使循环条件是固定的,你也会错过第一个字符,然后打印终止NUL,这两个都没有意义。只有在您确认其在范围内并完成了您需要执行的操作后,才应增加a。所以,printf()它,然后增加它。

2和3似乎最容易通过使用for循环而不是手动拆分循环变量的初始化,测试和递增。您还应该使用正确的索引类型:如果您想打印一个包含数百或数十亿个字符的字符串,int不够宽,而且它的风格也不好。所以:

#include <stddef.h> /* size_t */

for (size_t a = 0; argv[1][a] != '\0'; ++a) {
    printf("%c\n", argv[1][a]);
}

答案 2 :(得分:0)

我看到的分段错误的唯一原因是if语句的子表达式

if (argc == 2 && isalpha(argv[1]))
                 ^^^^^^^^^^^^^^^^ 

指定了不正确类型的参数。表达式argv[1]的类型为char *,而函数需要一个字符类型的对象,该对象被解释为unsigned char并被提升为int类型。

因此,当提升的参数具有负值(EOF值除外)时,函数isalpha具有未定义的行为。

来自C标准(7.4字符处理<ctype.h>

  

1标题<ctype.h>声明了几个有用的函数   分类和映射字符.198)在所有情况下,参数都是   一个int,其值应表示为无符号   char或应等于宏EOF的值。如果论证有   任何其他值,行为都是未定义的。

您应该像

一样编写if语句
if (argc == 2 && isalpha( ( unsigned char )argv[1][0] ) )

或喜欢

if (argc == 2 && isalpha( ( unsigned char )*argv[1] ) )

如果参数不是空字符串,那么while语句中还会有一个bug,它永远不会执行。我认为你的意思是以下

    int a = 0;

    while ( argv[1][a] != '\0' )
    {
        printf("%c\n", argv[1][a]);
        a++;
    }

或者例如

    int a = 0;

    while ( argv[1][a] )
    {
        printf("%c\n", argv[1][a++]);
    }