如何修复提取句子数组中偶数索引值并将其与奇数索引值组合的代码?

时间:2019-03-22 23:43:55

标签: c arrays

基本上,我的代码应该通过取出所有偶数索引值(从0开始)和奇数索引值并将奇数索引值之前的偶数索引值加密来对句子(或单词)进行加密。 例如,类似“ test”(0)t(1)e(2)s(3)t的单词应打印为(0)t(2)s(1)e(3)t或“ tset”。不应打印任何数字,我只是使用它们来显示奇数和偶数索引值。 我的代码有时可以运行,具体取决于运行的位置。我似乎在代码块和尝试的在线编译器之间得到了不同的结果。我怀疑这种不一致一定是一个更大的问题。谁能帮助我看看我在做什么错,以便我最终能够理解并纠正错误?

我尝试使用一个计数器将偶数和奇数索引值都输入到一个数组中,但是我也遇到了错误,因此我决定将它们放入单独的数组中,然后使用strcat来组合它们。有没有一种方法可以使其与我在代码中显示的方法一起使用,还是应该回到上一个方法?

#include <stdio.h>
#include <string.h>
#define SIZE 1000

int main()
{
    char message[SIZE];
    char even[SIZE];
    char odd[SIZE];
    int length,j=0;
    printf("Enter a word or sentence.\n");
    fgets(message,SIZE,stdin);

    printf("Your message is: %s\n",message);
    message[strcspn(message, "\n")] = 0;
    length=strlen(message);
    printf("The length of the message is: %d\n",length);
    for(int i=0;i<length;i+=2){

        even[i/2]=message[i];

       // printf("%c\n",even[i/2]);
    }

    for(int i=1;i<length;i+=2){
        odd[j]=message[i];
        j++;
    }
    printf("The even letters are: %s\n",even);
    printf("The odd letters are: %s\n",odd);

    strcat(even,odd);
    printf("%s",even);


/*printf("\nFInalyy.");
   for(i=0;i<=count;i++)
      for(j=i+1;j<=count;j++){
         if(strcmp(allmessages[i],allmessages[j])>0){
            strcpy(temp,allmessages[i]);
            strcpy(allmessages[i],allmessages[j]);
            strcpy(allmessages[j],temp);
         }
      }
   printf("The original messages in alphabetical order are: ");
   for(i=0;i<=count;i++)
      puts(allmessages[i]);*/
    return 0;
}

当我输入“ test”或“ sentence”之类的单词时,它可以完美地工作。有时我会输入诸如“这是一个测试句子”之类的句子,它会很好地工作,然后一次它将打印出一些随机垃圾信件以及加密的句子。我想知道如何解决此问题,并想知道为什么它多次与同一个条目完美配合后才停止。我使用https://www.onlinegdb.com/online_c_compiler进行了最后几次测试,因此我的结果基于此。

成功的结果:

Successful Result

使用相同条目的不成功结果:

Unsuccessful Result using the same entry

3 个答案:

答案 0 :(得分:1)

您可以根据用户输入的evenstart的总长度,简单地使用两个索引来构建加密的字符串(例如oddstartmessage),从而略微缩短方法。 evenstart = 0;oddstart = (msglen + 1) / 2;

然后循环遍历用户输入的消息中的字符,这些字符分别写在encrypt[evenstart++]的偶数字符和encrypt[oddstart++]的奇数字符。 (如果要将其用作输出字符串,请不要忘记使用 nul-terminate encrypt

将其放在一起即可:

#include <stdio.h>
#include <string.h>

#define MAXC 1024

int main (void) {

    char message[MAXC],
        encrypt[MAXC];
    size_t len, evenstart = 0, oddstart;

    fputs ("enter message: ", stdout);
    if (!fgets (message, MAXC, stdin)) {    /* validate message entered */
        fputs ("(user canceled input)\n", stdout);
        return 1;
    }

    message[(len = strcspn(message, "\r\n"))] = 0;  /* trim '\n', get len */
    oddstart = (len + 1) / 2;       /* get oddstart (add 1 before divide) */

    for (size_t i = 0; i < len; i++)        /* loop over each char */
        if (i & 1)      /* if odd, write char at oddstart */
            encrypt[oddstart++] = message[i];
        else            /* if even, write at evenstart */
            encrypt[evenstart++] = message[i];
    encrypt[len] = 0;   /* nul-terminate */

    printf ("message : '%s'\nencrypt : '%s'\n", message, encrypt);
}

注意:如果需要,您可以使用i % 2来检查偶数/奇数,如果二进制位是{{ 1}}是奇怪的,否则是偶数-由您决定)

使用/输出示例

i & 1

仔细研究一下,如果您有任何疑问,请告诉我。

答案 1 :(得分:1)

C中的字符串以空字节('\ 0'或ascii值0)终止,只是它知道字符串的结尾。由于偶数和奇数字符数组没有以空字节终止,因此strcat不知道何时停止追加字符。因此,您看到的垃圾值是因为strcat会不断追加字符,直到您幸运地在内存中找到0。

答案 2 :(得分:0)

C中的字符串不知道它们的长度,它们只是指针。字符串必须以空字符结尾,以便printfstrlen之类的函数知道何时停止。

char even[SIZE];
char odd[SIZE];

此时evenodd都包含当时内存中的所有垃圾。

for(int i=0;i<length;i+=2){
    even[i/2]=message[i];
}

for(int i=1;i<length;i+=2){
    odd[j]=message[i];
    j++;
}

现在oddeven的开头已被填充,但它们不是以null结尾的。

printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);

这些操作将从evenodd指向的位置开始,打印您在其中放置的字符,然后继续打印内存中的所有垃圾,直到碰巧遇到空字符为止。


解决方法是使用memset将内存清零。

memset(even, '\0', SIZE);
memset(odd, '\0', SIZE);

或者一旦完成对evenodd的终止操作,请确保它们为空。

for(i=0;i<length;i+=2){
    even[i/2]=message[i];
}
even[i/2] = '\0';

for(i=1;i<length;i+=2){
    odd[j]=message[i];
    j++;
}
odd[j] = '\0';

旁注evenodd循环可以使用相同的技术完成。

for( i=0,j=0; i<length; i+=2,j++ ) {
    even[j]=message[i];
}
even[j] = '\0';

for( i=1,j=0; i<length; i+=2,j++ ) {
    odd[j]=message[i];
}
odd[j] = '\0';

然后我们可以观察到唯一的区别是我们开始阅读message的位置。这意味着我们可以将其放在函数中,并始终记住将结果终止为null。

void copy_every_other_character(const char *src, char *dst) {
    int i,j,length = 0;
    length = strlen(src);
    for( i=0,j=0; i<length; i+=2,j++ ) {
        dst[j] = src[i];
    }
    dst[j] = '\0';
}

copy_every_other_character(message, even);
copy_every_other_character(message+1, odd);

message上加1表示copy_every_other_character将获得指向message的第二个字符的指针,然后从那里继续。如果message01234,它将看到1234