[英]Combining two strings into one string which eliminates the same letters in C
您好,我在编程方面还很陌生,想向您学习一些知识:)我正在使用.c编写程序,但我陷入了困境。 我想获得3个或更多输入,最大5个字符的大小。 (例如:HELLO,HI,GOOD,BYE),我想将它们堆叠在一个新字符串中,该字符串仅从这4个字符串中一次保存相同的字母(例如:H,E,L,L,O,I,G,D ,通过)
#include <stdio.h>
#include <string.h>
int main(void) {
char first[5], second[5], third[5], fourth[5];
printf("Enter 1st word: \n"); scanf(" %5s", &first);
printf("Enter 2nd word: \n"); scanf(" %5s", &second);
printf("Enter 3rd word: \n"); scanf(" %5s", &third);
printf("Enter 4th word: \n"); scanf(" %5s", &fourth);
char stack[21]; // i want a new string like this and then combine first 4 strings
// in this string...
return 0;
}
希望您可以让我知道我可以采用哪种方式。 (我也是该网站的新成员。我搜索了此文件,但找不到。抱歉,它存在。)
首先,对您的代码进行一些注释:
first
,…, fourth
数组的长度至少应为6。 stack
数组应能够容纳21个字符(对于终止NUL字节,还是1个)。 (也由user3121023的评论提及。) scanf
读取字符串,请传递char *
类型的参数,而不是char (*)[6]
。 first
已经衰变为char *
所以不要另外获取其地址(如&first
)。 打开编译器的警告(至少使用-Wall
)以了解此类错误。 (在我键入此答案时, Derre0405也提到过。) scanf
使用是不安全的。 如果用户输入的字符串长于5个字符,则您将阅读数组末尾之外的内容。 您可以修改格式说明符以读取%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
只是数字这一事实。 因此,您可以创建一个包含256个元素(有256个不同的char
)的数组,这些元素最初都设置为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
语句中对其求值。 最后,该值通过后递增运算符递增(但仅在比较之后)。
不要忘了以结尾的NUL字节终止stack
。
请按以下方式更新您的代码:
printf("Enter 1st word: \n"); scanf(" %s", &first);
至
printf("Enter 1st word: \n"); scanf(" %s", first);
请更新到其他行。
尝试:
#include <stdio.h>
#include <string.h>
int main(void) {
char strings[4][6];
printf("Enter 1st word: \n"); scanf(" %s", strings[0]);
printf("Enter 2nd word: \n"); scanf(" %s", strings[1]);
printf("Enter 3rd word: \n"); scanf(" %s", strings[2]);
printf("Enter 4th word: \n"); scanf(" %s", strings[3]);
char stack[21]; // This needs to be pretty much bigger than all combined just in case
// Initialize the stack string to 0 length
stack[0] = '\0'
// Move through each word
for(unsigned char word = 0; word < 4; word++){
// Move through each letter of each word
for(unsigned char letter = 0; letter < strlen(strings[word]); letter++){
// Test to see if the current letter is within the current stack string
unsigned char schar;
for(schar = 0; schar < strlen(stack); schar++){
if(stack[schar] == strings[word][letter]) break;
}
if(schar >= strlen(stack)){
unsigned char sstacklen = strlen(stack);
stack[sstacklen] = strings[word][letter];
stack[sstacklen+1] = '\0';
}
}
}
return 0;
}
这应该可以满足您的需求,这是一个快速的编写过程,因此可能会有一些小错误!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.