首先对您的代码进行一些评论:
- 正如其他人在评论中已经提到的那样,您需要一个大小为n + 1 的缓冲区来保存一个n字符串。这是因为在 C 中,字符串的长度不会存储在任何地方。相反,一个特殊的 NUL 字节被附加到标记其结束的字符串中。因此,您的
first
, ...,fourth
数组的长度应至少为 6。
- 如果最坏的情况发生并且用户输入四个不相交的单词,每个单词值 5 个字符怎么办?然后你的组合字符串将计算 20 个字符。所以你的
stack
数组应该能够容纳 21 个字符(终止 NUL 字节也是 1 个)。(user3121023的评论也提到了。)
- 要使用 读取字符串
scanf
,请传递类型的参数char *
,而不是char (*)[6]
。 first
已经衰减到char *
所以不要另外取它的地址(如&first
)。打开编译器的警告(至少使用-Wall
)以了解此类错误。(在我输入这个答案时, Dere0405也提到过。)
- 您的使用
scanf
是不安全的。如果用户输入的字符串长度超过 5 个字符,您将读取超出数组末尾的内容。您可以将格式说明符修改为 read%5s
以告知scanf
在第 5 个字符之后停止阅读。但是,这会在行尾留下多余的字符。更好的选择是使用fgets
或getline
读取整行输入。或者,只需将字符串作为命令行参数传递(我的首选解决方案)。
现在到实际问题:
我不会给你一个完整的解决方案,而只是一些提示,因为这看起来很像家庭作业。(不幸的是,其他人已经给了你完整的代码,所以你可能会忽略我的回答。)
您必须遍历所有五个字符串并检查每个字符是否已添加到stack
. 如果是,请继续,否则,将其附加到stack
. 要遍历字符串,我们可以使用以下成语。
int i;
for (i = 0; first[i]; ++i)
printf("The character at position %d is '%c'\n", i, first[i]);
或者,如果我们不需要引用当前索引,下面的成语更简洁。
char * pos;
for (pos = first; *pos; ++pos)
printf("The current character is '%c'\n", *pos);
请注意我们如何使用这一事实first
——作为一个 C 字符串——以一个 NUL 字节终止,该字节的计算结果为 false。否则,我们将不知道在哪里停止迭代。
既然我们知道如何遍历字符串的字符,那么我们如何检查是否已经添加了字符?想到了两个解决方案:
循环stack
并比较每个元素与当前有问题的字符。虽然对于您的短字符串,这可能是首选方法,但对于较长的字符串,它将变得低效。
为每个字符创建一个计数器,并在添加到stack
. char
您可以使用s 只是数字的事实。因此,您可以创建一个包含 256 个元素(有 256 个不同char
的 s)的数组,所有元素最初都设置为 0,然后增加当前添加的字符的位置。例如:
int counters[256];
memset(counters, 0, sizeof(counters)); /* fill with 0s */
然后在您的代码中:
if (counters[(unsigned char) (*pos)]++)
{
/* Character was already added. Do nothing. */
}
else
{
/* Character was not added yet. Add it to stack. */
}
这if (counters[(unsigned char) (*pos)]++)
有点棘手。首先,*pos
引用指针pos
以产生当前字符,然后将其解释为一个,unsigned char
因为数组不能有负索引。counters
然后在数组中查找该位置并在if
语句中进行评估。最后,该值通过后增量运算符递增(但仅在比较之后)。
不要忘记以stack
NUL 字节结尾。