我刚刚开始倾向于C,所以我不太了解它。我们给出的程序告诉我们编写一个插入排序程序,它按空格分隔20个字符串,然后按字母顺序排序并按顺序打印出来。这让我很困惑,因为C没有String数据类型(至少据我所知)。字符串不是字符串吗?这是我得到的:
#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 20
void InsertionSort(char list[]);
void main()
{
int index;
char strings[MAX_STRINGS];
/* Get input */
printf("Enter %s strings.\n", MAX_STRINGS);
for (index = 0; index < MAX_STRINGS; index++)
{
char tempString[100];
printf("Input string %d : ", index);
scanf("%s", &tempString[0]);
strings[index] = tempString;
}
InsertionSort(strings);
printf("\nThe input set, in alphabetical order:\n");
for (index = 0; index < MAX_STRINGS; index++)
{
printf("%s\n", strings[index]);
}
}
void InsertionSort(char list[])
{
int unsorted;
int sorted;
char unsortedItem;
for(unsorted = 1; unsorted < MAX_STRINGS; unsorted++)
{
unsortedItem = list[unsorted];
for (sorted = unsorted - 1; (sorted >= 0) && (list[sorted] > unsortedItem); sorted--)
{
list[sorted + 1] = list[sorted];
}
list[sorted + 1] = unsortedItem;
}
}
我对C和C语法完全陌生,我发现它很混乱。此程序无法正常工作。它正在做的是它允许我输入20个字符串,但是没有任何东西被排序并且它什么也没有打印出来。关于如何解决这个问题的任何想法?另外,有什么想法我怎么能把它输入到我输入单个句子的地方,每个字符串用空格分隔?例如,如果我打字,“我正在学习如何用C编程,现在我不喜欢它。”这会给我16个字符串。 “我”,“我”,“学习”等等。谢谢。
答案 0 :(得分:3)
原始代码存在一些问题:
1)您无法使用=
复制字符串;使用strncpy
即可(使用=
仅指定指针)。
2)字符串是一个字符数组;因此,字符串数组是字符数组的数组(因此您的InsertionSort
签名是错误的)。请注意,C字符串是空终止的,这意味着值为0的字节表示字符串的结尾(这非常重要,如果您忘记其他所有内容,请记住这一点)。
3)%s
期待char*
;这一行产生UB:printf("Enter %s strings.\n", MAX_STRINGS);
。您想要的是%d
(请阅读printf
格式说明符)。
4)你不能使用普通算术运算符来比较字符串;那些比较指针。您需要使用strcmp
。
5)插入排序算法的实现是错误的。
6)标准允许的main
声明版本有几个版本,char main
不是其中之一。在这种情况下,只需使用int main
。
以下是您的代码的固定版本:
#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 20
#define MAX_STRING_LEN 200
void InsertionSort(char list[MAX_STRINGS][MAX_STRING_LEN]);
int main()
{
int index;
char strings[MAX_STRINGS][MAX_STRING_LEN];
/* Get input */
printf("Enter %d strings.\n", MAX_STRINGS);
for (index = 0; index < MAX_STRINGS; index++)
{
printf("Input string %d : ", index);
scanf("%199s", strings[index]); // limit the width so we don't go past the buffer
strings[index][sizeof(strings[index]) - 1] = '\0';
}
InsertionSort(strings);
printf("\nThe input set, in alphabetical order:\n");
for (index = 0; index < MAX_STRINGS; index++)
{
printf("%s\n", strings[index]);
}
}
void InsertionSort(char list[MAX_STRINGS][MAX_STRING_LEN])
{
for (int i = 1; i < MAX_STRINGS; i++)
{
int j = i;
while (j > 0 && strcmp(list[j - 1], list[j]) > 0)
{
char tmp[MAX_STRING_LEN];
strncpy(tmp, list[j - 1], sizeof(tmp) - 1);
tmp[sizeof(tmp) - 1] = '\0';
strncpy(list[j - 1], list[j], sizeof(list[j - 1]) - 1);
list[j - 1][sizeof(list[j - 1]) - 1] = '\0';
strncpy(list[j], tmp, sizeof(list[j]));
list[j][sizeof(list[j]) - 1] = '\0';
--j;
}
}
}
起初这可能有点压倒性,但要慢慢仔细阅读,你应该没有问题。
= '\0'
或strncpy
之后的scanf
- 这些函数不会隐式地终止字符串,因此我们必须手动执行此操作 - 您可能会在不执行此操作的情况下离开几次,但从长远来看,它最终会回到你身边。保持安全,养成习惯。
其他人:如果你发现任何错误,请告诉我 - 已经很晚了,我已经累了。
关于您在评论中提出的问题:
1)为什么我从for
循环中的1开始?
因为我稍后提到list[j - 1]
,并且j
设置为i
(最初)的值,所以它不能小于1
或我们是使用负指数。有关算法的说明,请参阅here。
2)如何读取整行的字符串,包括空格?
最好的解决方案是使用fgets
。请注意,它有一个怪癖:它还将\n
字符存储在数组中。如果您不想要它,则必须手动将其删除。
3)什么是tmp
?
这只是一个临时的char
缓冲区,所以我可以根据算法的要求交换这两个字符串。这不是特定于字符串,通常交换两个变量,你需要第三个,临时的(除非你选择一些脏的XOR黑客)。
答案 1 :(得分:1)
使用此功能按字母顺序对字符串进行排序:
int s_bubblesortA(int argc,char **argv)
{
int i , j = 0;
char *p_1 , *p_2 , *tmp;
while( j < argc )
{
for( i = 0 ; i < argc - j - 1 ; i++ )
{
p_1 = argv[i] , p_2 = argv[i+1];
while( *p_1 && *p_2 )
{
if( *p_1 < *p_2 )
break;
else if( *p_1 > *p_2 || ( ! *(p_2 + 1) && ( *p_1 == *p_2 ) && *(p_1+1) ) )
{
tmp = argv[i];
argv[i] = argv[i+1];
argv[i+1] = tmp;
break;
}
p_1++;
p_2++;
}
}
j++;
}
return 0;
}
注意:请查看此链接,以便我对类似帖子的完整答案。sort words alphabeticaly in C