- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
刚开始学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 个字符串。 “我”、“我”、“学习”等。谢谢。
最佳答案
原代码的几个问题:
1) 不能使用=
复制字符串;使用 strncpy
为此(使用 =
仅分配指针)。
2) 字符串是字符数组;因此,字符串数组是字符数组的数组(因此您的 InsertionSort
签名是错误的)。请注意,C 字符串以 null 结尾,这仅意味着值为 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;
}
}
}
一开始可能有点不知所措,但慢慢仔细阅读,你应该没有问题。
strncpy
或 scanf
之后的 = '\0'
- 这些函数不会隐式以 null 终止字符串,因此我们有手动执行此操作 - 您可能会在不执行几次的情况下逃脱,但从长远来看,它最终会回到您身边。保持安全并养成习惯。
其他所有人:如果您发现任何错误,请告诉我 - 已经很晚了,我很累。
关于您在评论中的问题:
1) 为什么我在 for
循环中从 1 开始?
因为我稍后会引用 list[j - 1]
,并且 j
设置为 i
的值(初始),它可以不能小于 1
否则我们将使用负索引。参见 here算法的描述。
2) 如何读取整行字符串,包括空格?
最好的解决方案是使用 fgets
.请注意,它有一个怪癖:它也在数组中存储了 \n
字符。如果您不想要它,则必须手动将其删除。
3) tmp
有什么用?
这只是一个临时的 char
缓冲区,因此我可以根据算法的要求交换这两个字符串。这并非特定于字符串,通常要交换两个变量,您需要第三个临时变量(除非您选择一些肮脏的 XOR hack)。
关于c - 字符串插入排序程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33724720/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!