问题描述
菜鸟问题,可能。我查看了其他答案,并尝试了他们所做的。但我每次仍然收到错误。这是我的凯撒密码程序的第一个片段。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
char message[81];
char cipher[81];
do
{
printf("Enter a message: ");
scanf("%[^\n]",&message);
//scanf("%s",&message) = error as well
printf("Test"); //to see if it prints. doesn't print,so seg fault must be on above line
if (!isalpha(message))
{
printf("Invalid input. Enter only letters.\n");
}
else
{
valid = 1;
}
} while (valid == 0);
// ...
作为输入,我将输入任何内容 - 一个字符串、一个字符、一个数字等,但我仍然遇到段错误。
我正在使用 -W -Wall -ansi -pedantic 编译我的代码,但没有收到与段错误相关的错误或警告。
解决方法
对于初学者来说,这个调用中参数的类型
scanf("%[^\n]",&message);
无效。你需要写
scanf("%[^\n]",message);
在下一次调用 scanf 之前,您还需要从输入缓冲区中删除换行符 '\n'。
函数 isalpha
需要一个 char
类型的对象。但是您传递的是 char *
类型的表达式。
if (!isalpha(message))
调用未定义的行为。
还有一个问题出现在您的代码片段中,其中声明了变量 valid
。
如果你想检查一个字符串是否包含字母符号或/和空格,那么你需要检查输入字符串的所有符号。
这是一个演示程序。
#include <stdio.h>
#include <ctype.h>
int all_letters( const char *s )
{
while ( *s && isalpha( ( unsigned char )*s ) ) ++s;
return *s == '\0';
}
int main(void)
{
char message[81];
int valid = 0;
do
{
printf( "Enter a message: " );
scanf( "%80[^\n]",message );
while ( getchar() != '\n' );
valid = all_letters( message );
if ( !valid )
{
printf( "Invalid input. Enter only letters.\n" );
}
} while ( !valid );
return 0;
}
它的输出可能看起来像
Enter a message: 123
Invalid input. Enter only letters.
Enter a message: Hello
,
我在 valgrind
下运行了这段代码,错误实际上是在这里的这一行:
if (!isalpha(message))
请记住,isalpha
接受一个 char
(技术上是一个 int
,但预计它只包含一个字符)。通过传入 message
,您传入的是 char [81]
,它的类型不正确。
令我困惑的是,即使警告级别提高到最大值,它仍然可以编译和运行,因为没有从 char [81]
到单个 char
的隐式转换。
要解决此问题,您需要更改您在此处编写的代码,以便更明确地测试输入的所有字符是否为字母。您可能还想检查 scanf
的返回值以确保它不会失败并在失败时清除 stdin
中的无效字符。