繁体   English   中英

将两个字符串合并为一个字符串,从而消除了C中的相同字母

[英]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;
}

希望您可以让我知道我可以采用哪种方式。 (我也是该网站的新成员。我搜索了此文件,但找不到。抱歉,它存在。)

首先,对您的代码进行一些注释:

  • 正如其他人在评论中已经提到的那样,您需要一个大小为n + 1的缓冲区来容纳一个n字符串。 这是因为在C语言中,字符串的长度未存储在任何地方。 而是在字符串的末尾附加一个特殊的NUL字节。 因此, first ,…, fourth数组的长度至少应为6。
  • 如果发生最坏的情况并且用户输入四个不连续的单词(每个单词不超过5个字符)怎么办? 然后,您的组合字符串将包含20个字符。 因此,您的stack数组应能够容纳21个字符(对于终止NUL字节,还是1个)。 (也由user3121023的评论提及。)
  • 要使用scanf读取字符串,请传递char *类型的参数,而不是char (*)[6] first已经衰变为char *所以不要另外获取其地址(如&first )。 打开编译器的警告(至少使用-Wall )以了解此类错误。 (在我键入此答案时, Derre0405也提到过。)
  • 您对scanf使用是不安全的。 如果用户输入的字符串长于5个字符,则您将阅读数组末尾之外的内容。 您可以修改格式说明符以读取%5s以告诉scanf在第5个字符之后停止读取。 但是,这将在行尾保留多余的字符。 更好的选择是使用fgetsgetline读取整行输入。 或者,只需将字符串作为命令行参数传递(我的首选解决方案)。

现在到实际问题:

我不会为您提供完整的解决方案,而只会给您一些提示,因为这看起来很像家庭作业。 (不幸的是,其他人已经给了您完整的代码,因此您可能会忽略我的回答。)

您必须遍历所有五个字符串,并检查每个字符是否已添加到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。 否则,我们将不知道在哪里停止迭代。

现在,我们知道了如何遍历字符串的字符,如何检查是否已经添加了字符? 有两种解决方案:

  1. 遍历stack并将每个元素与当前有问题的字符进行比较。 虽然对于您的短弦,这可能是选择的方法,但对于较长的弦,它将变得效率低下。

  2. 为每个字符创建一个计数器,并在添加到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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM