我写了一个程序来查找最长的单词并打印它。
我的代码是:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int MaxWord(char text[],char[]);
int main (void){
char text[1000];
char word[1000];
int max;
printf("geben Sie den Text bitte : ");
gets(text);
max=MaxWord(text,word);
printf("ist mit %d Zeichen das laengste wort im Textnnn",max);
return 0;
}
int MaxWord(char text[], char word[])
{
char i;
int ctr=0;
int max=0;
int len;
char begin=0;
len=strlen(text);
for(i=0;i<len+1;i++)
{
if(isalpha(text[i]))
{
if(ctr==0)
{
begin=i;
}
ctr++;
}
else
{
if(ctr>max)
{
max=ctr;
}
ctr=0;
}
}
strncpy(word,begin,max);
printf("%s ",word);
return max;
}
错误为:
错误#2140:在"strncpy"的参数2中键入错误;应为"const char*restrict",但实际为"char"。
我该怎么解决这个问题?
首先,您不应该使用gets()函数。请改用scanf。另请参阅http://www.cplusplus.com/reference/cstring/strncpy/
函数strncpy需要一个const char*(这样可以确保函数不会修改源字符串),而您正在向它传递一个char。因此出现了错误。请修改您的函数以传递一个字符指针。
您需要重新检查您的逻辑,并通过传递正确的源字符串来修复strncpy调用。
MaxWord
中的逻辑存在缺陷:您总是试图复制遇到的长度最长的最后一个单词。类型char
不适合于i
和begin
,因为它们是text
中潜在地大于127
的偏移。
此外,strncpy
并不像您认为的那样,它是一个容易出错的函数,可能无法null终止目标缓冲区。请勿使用此功能。
也不要使用gets
,因为它不能安全使用,无效输入会导致缓冲区溢出。
这是一个更正的版本:
int MaxWord(const char *text, char *word) {
int i, ctr = 0, max = 0, len, begin = 0, best = 0;
len = strlen(text);
for (i = 0; i < len; i++) {
if (isalpha((unsigned char)text[i])) {
if (ctr == 0) {
begin = i;
}
ctr++;
} else {
if (ctr > max) {
best = begin;
max = ctr;
}
ctr = 0;
}
}
memcpy(word, test + best, max);
word[max] = ' ';
printf("%s ", word);
return max;
}
将text[i]
强制转换为(unsigned char)
似乎令人惊讶,但isalpha()
被定义为采用具有unsigned char
或常数EOF
(通常定义为-1
)值的int
自变量。如果编译器认为char
是有符号类型,则text
中具有高位集的字符将被视为负数,并且在传递给isalpha
时将进行符号扩展,这可能会调用不正确或未定义的行为。
代码的另一个问题是单词边界的确定:如果将laengste
正确地键入为längste
,则isalpha()
可能会错误地将编码ä
的一个或多个字符视为分隔符而不是字母。欢迎来到角色编码的复杂世界!