C语言中字符串的奇怪排序
我想解决这个问题。问题指出: “初学者”是一个字母按字母顺序排列的单词。 编写一个程序,确定给定的单词是否正确 是否为初学者,如果为初学者,则打印1,如果为非初学者,则打印0 现在我解决了这个问题,我将对字符串进行排序,如果排序后的字符串与原始字符串相同,那么它将是初学者。但在C代码中,它给出了输入的wied结果。代码如下,包含输入和输出 //由我添加到输出中进行解释 产出1 排序前的原始字符串=abcdef 排序前复制的原始字符串=abcdef 排序后的原始字符串=fedabc//应保持abcdef,如果遵循desc sort,则应为fedcba 排序后复制的原始字符串=abcdef abcdef不是一个初级词汇 输入2 fedcba 产出2 排序前的原始字符串=fedcba 排序前复制的原始字符串=fedcba 排序后的原始字符串=abcdef//这里是正确的 排序后复制的原始字符串=fedcba fedcba不是一个初级词汇 您可以检查其他输入,并将看到排序没有按应有的方式工作。现在我对C语言的内存管理不是很在行C语言中字符串的奇怪排序,c,string,sorting,C,String,Sorting,我想解决这个问题。问题指出: “初学者”是一个字母按字母顺序排列的单词。 编写一个程序,确定给定的单词是否正确 是否为初学者,如果为初学者,则打印1,如果为非初学者,则打印0 现在我解决了这个问题,我将对字符串进行排序,如果排序后的字符串与原始字符串相同,那么它将是初学者。但在C代码中,它给出了输入的wied结果。代码如下,包含输入和输出 //由我添加到输出中进行解释 产出1 排序前的原始字符串=abcdef 排序前复制的原始字符串=abcdef 排序后的原始字符串=fedabc//应保持abc
是否有任何内存问题/调整导致了此类问题?您正在比较字符、字符,而不是整数、int 将比较函数更改为
int cmpfunc (const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
您正在比较字符、字符,而不是整数、int 将比较函数更改为
int cmpfunc (const void * a, const void * b)
{
return ( *(char*)a - *(char*)b );
}
只需检查字符串中的字符是否为非降序字符,即可更有效地执行此操作:
int
is_abecedarian(char *s)
{
if(s[0]==0) return 1;
while(s[1] && s[0]<=s[1]) ++s;
return s[1]==0;
}
注意,我假设字符串s要么全是大写的,要么全是小写的。以及一种以递增数字顺序排列a-z的字符编码。只需检查字符串中的字符是否为非降序字符,即可更有效地执行此操作:
int
is_abecedarian(char *s)
{
if(s[0]==0) return 1;
while(s[1] && s[0]<=s[1]) ++s;
return s[1]==0;
}
注意,我假设字符串s要么全是大写的,要么全是小写的。一种字符编码,其a-z以递增的数字顺序排列。为了回答您的实际问题,这种编码失败的原因是您将数据作为int而不是char进行解引用。这意味着您取消引用的字节比需要的多,并且比较可能与“a”无关的字节根据ascii标准,a'为0x61。如果将“a”取消引用为int,则最终可能会得到0x61FFFFFF或0xFFFF61,具体取决于类型转换的实现方式。因此,您实际上并不是在比较字符,而是在比较字符和周围的字节。为了回答您的实际问题,此操作失败的原因是因为您将数据作为int而不是char取消引用。这意味着您取消引用的字节比需要的多,并且比较可能与“a”无关的字节根据ascii标准,a'为0x61。如果将“a”取消引用为int,则最终可能会得到0x61FFFFFF或0xFFFF61,具体取决于类型转换的实现方式。因此,您实际上不是在比较字符,而是在比较字符和周围的字节。字符不是整数。您不能期望前者的地址与指向后者的指针一起使用。在比较器中将int*更改为const char*。在排序之前复制了它,您希望得到什么结果?请注意,comparator.chars不是int。您不能期望前者的地址与指向后者的指针一起使用。在比较器中将int*更改为const char*。在排序之前复制了它,您希望得到什么结果?请注意比较器的更改。@tintinmj:因为这意味着您到达字符串末尾时没有找到前一个字符之前的字母顺序。@tintinmj:因为这意味着您到达字符串末尾时没有找到前一个字符之前的字母顺序。并且随机崩溃程序。并随机破坏程序。