2014-12-06 161 views
0

你好,我是在编程很新,想了解一些从你:) 我做以.c程序,我在stucked部分。 我想获得3个或更多的输入最多5个字符的大小。 (例如:HELLO,HI,GOOD,BYE) ,我想将它们堆叠在其保持相同的字母从这些4个字符串仅一次一个新的字符串 (实施例:H,E,L,L,O,I,G ,D,B,Y)组合两个字符串连接为一个字符串,它消除了在C相同的字母

#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; 
} 

我希望你能让我知道我可以做到这一点。 (我也是在该网站新我搜索了这一点,但我找不到很抱歉,如果它的存在。)

+0

你想在结果字符串中的字母是以任何特定的顺序? – 5gon12eder 2014-12-06 18:08:25

+0

@ 5gon12eder - 不,我只是想把这些字符串结合在一个字符串中去掉多余的字母。 – Gorki 2014-12-06 18:18:16

+1

我建议使堆栈数组[21]考虑到所有唯一字母(和null)的可能性。 – doppelheathen 2014-12-06 18:23:56

回答

1

首先在你的代码的一些意见:

  • 作为其他的评论已经提到一个人,你需要一个缓冲区的大小ň + 1举办的ñ字符串。这是因为在C中,字符串的长度不存储在任何地方。相反,将一个特殊的NUL字节附加到标记其结尾的字符串。因此,您的first,...,fourth阵列应该是长度至少为6
  • 如果最坏的情况发生,用户进入每四个价值500个字符不相交的话吗?然后你的组合字符串将计数20个字符。所以你的stack数组应该能够容纳21个字符(终止NUL字节也是1)。 (user3121023的评论提及)
  • 要使用scanf读取字符串,请传递类型为char *的参数,而不是char (*)[6]first已经衰减到char *,所以不要另外接收它的地址(如&first)。打开编译器的警告(至少使用-Wall)以获知此类错误。 (也由Dere0405提到,而我打字这个答案。)
  • 您使用的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字符串 - 终止与计算为false NUL字节。否则,我们不知道在哪里停止迭代。

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

  1. 循环遍历stack并将每个元素与当前正在讨论的字符进行比较。虽然对于你的短字符串,这可能是选择的方法,但对于更长的字符串来说,它会变得效率低下。

  2. 为每个字符创建一个计数器,并在每次添加到stack时递增。你可以使用这个事实,即char只是数字。所以你可以创建一个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 dreferences指针pos产生当前字符,然后将其解释为unsigned char,因为数组不能有负索引。然后,该位置在counters阵列中查找,并在if声明中进行评估。最后,通过增量后运算符增加该值(但仅在比较之后)。

不要忘记终止stack与最后的NUL字节。

+0

非常感谢你,那就是我一直在寻找的东西:)我要亲自尝试一下,看看你的类型:) – Gorki 2014-12-06 19:26:43

0

请更新您的代码如下:

printf("Enter 1st word: \n"); scanf(" %s", &first); 

printf("Enter 1st word: \n"); scanf(" %s", first); 

请更新至其他行。

+0

这是为什么?不应该在scanf中的变量有&? – wadie 2014-12-06 18:26:47

+0

嗯,这是我只能肯定的事^^,我想我没有错那里,我也没有得到任何警告,而执行 – Gorki 2014-12-06 18:29:49

+0

@Gorki你*应*得到*编译器警告*。执行时,它只是调用未定义的行为,所以任何事情都可能发生或可能不会发生。看到我的答案多一点解释。 – 5gon12eder 2014-12-06 19:22:17

0

尝试:

#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; 
} 

这应该为你想要什么样的工作,这是一个快速的写,所以可能会有小的误差!

相关问题