某些输入上的分段错误,而不是其他输入

时间:2012-12-13 10:28:28

标签: c segmentation-fault user-input

这是我写的一个函数,它已经有一些调试元素。当我输入“y”或“Y”作为输入时,我在运行时遇到分段错误。当我输入任何其他值时代码运行。 seg故障在扫描后启动并给出响应,但在输出“scan working”行之前。不知道为什么它只会对这些值起作用。如果有人需要函数调用我也有。

query_user(char *response [10])
{
    printf("response after query call before clear=%s\n",response);
    strcpy(response,"");
    printf("response after clearing before scan=%s\n",response);
    printf("Enter another person into the line? y or n\n");
    scanf("%s", response);
    printf("response after scan=%s\n",response);
    printf("scan worked");
}

main()
{
    char response [10]; 
    strcpy(response,"y"); 
    printf("response=%s\n",response); 
    printf("When finished with program type \"done\" to exit\n"); 
    while (strcmp(response,"done") != 0)
    {
        printf("response after while loop and before query call=%s\n",response);
        query_user(&response);
    }
}

输出错误:

response after query call before clear=y
response after clearing before scan=
Enter another person into the line? y or n
y
response after scan=y
Segmentation Fault (core dumped)

输出非错误:

response after query call before clear=y
response after clearing before scan=
Enter another person into the line? y or n
n
response after scan=n
scan worked
Cycle number 0
(program continues to run outside this function)

3 个答案:

答案 0 :(得分:2)

您对query_user的参数声明是错误的。你已经声明了一个指向char的指针数组。你需要一个简单的char缓冲区。像这样:

query_user(char response[])

query_user(char* response)

使用您喜欢的任何一种。

当您调用该函数时,您可以这样做:

query_user(response);

另外我要指出您对main的声明不正确。你应该使用

int main(void)

答案 1 :(得分:0)

你在做什么并不完全安全。

如果用户的磁带超过标签大小,会发生什么? (可能是Segfault)。

你真的应该使用像scanf这样的东西(“%9s ”,响应)(你必须在它之后清空缓冲区!):

(标签尺寸= 10的示例):

query_user(char *response)
{
    printf("response after query call before clear=%s\n",response);
    strcpy(response,"");
    printf("response after clearing before scan=%s\n",response);
    printf("Enter another person into the line? y or n\n");
    scanf("%9s", response);
    clean_buffer();
    printf("response after scan=%s\n",response);
    printf("scan worked");
}

void clean_buffer()
{
   int c;
   while ((c = getchar ()) != '\n' && c != EOF);
}

希望它有所帮助!

答案 2 :(得分:0)

首先,您发布的代码不会重现该问题。我使用Gcc 4.6.2在Linux上进行了测试,在使用Visual Studio 2010的Windows上进行了测试。在两种情况下,使用您的确切代码我的输出是:

  

响应= Y
  完成程序类型“完成”后退出
  while循环之后和查询之前的响应= y
  在clear = y之前的查询调用之后的响应   扫描前清除后的响应=
  输入另一个人进入该行? y或n
  ÿ
  扫描后的响应= y
  在while循环之后和查询调用之前扫描workingresponse = y
  在clear = y之前的查询调用之后的响应   扫描前清除后的响应=
  输入另一个人进入该行? y或n

因此,为了更好地诊断,我们需要一组完整的代码来显示这个问题。发布的代码有很多警告(不确定它们是否在您的基础上),有时忽略警告会让您陷入困境:

  • main应该返回intint main()
  • 在主页末尾return 0;
  • 返回
  • query_user需要void返回类型:void query_user()
  • strcpy需要char *你给它一个char **

对于最后一点,您可以通过将数组传递给函数来修复它,例如:

 query_user(response); // remove the & operator

query_user()的标题需要更改,例如:

 query_user(char response [10]) // remove the * operator

另请注意,scanf会在'\n'上留下stdin个字符,以确保您不会消耗,因为您可以在%s之前放置一个空格:

scanf(" %s", response);

我不认为这会产生很大的影响,但请确保你做出改变。请将更新发布到实际显示错误的代码中。