【问题标题】:How to fix code that extracts even numbered index values in an array of a sentence and combines it with odd numbered index values?如何修复在句子数组中提取偶数索引值并将其与奇数索引值组合的代码?
【发布时间】:2019-03-22 23:43:55
【问题描述】:

基本上,我的代码应该通过取出所有偶数索引值(从 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;
}

当我输入“测试”或“句子”之类的词时,它可以完美运行。有时我输入诸如“这是一个测试句子”之类的句子,它会完美地工作,然后有一次它会打印出一些随机的垃圾字母以及加密的句子。我想知道如何解决这个问题,并了解为什么它在同一个条目上完美运行几次然后就停止了。我最近几次使用https://www.onlinegdb.com/online_c_compiler 对其进行了测试,所以我的结果就是基于此。

成功的结果:

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

【问题讨论】:

  • 将文本作为文本发布比将文本作为图片发布更有用。请用文字替换图片。

标签: c arrays


【解决方案1】:

您可以采取一种稍微短一些的方法,只需使用两个索引来根据用户输入的message 的总长度来构建您的加密字符串(如evenstartoddstart)。 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 来检查偶数/奇数,或者简单地使用i &amp; 1 -- 在二进制中,如果个位为1,则为奇数,否则它甚至 - 由你决定)

使用/输出示例

$ ./bin/encrevenodd
enter message: tes
message : 'tes'
encrypt : 'tse'

$ ./bin/encrevenodd
enter message: test
message : 'test'
encrypt : 'tset'

$ ./bin/encrevenodd
enter message: tests
message : 'tests'
encrypt : 'tsset'

$ ./bin/encrevenodd
enter message: my dog has fleas
message : 'my dog has fleas'
encrypt : 'm o a laydghsfes'

检查一下,如果您有任何问题,请告诉我。

【讨论】:

    【解决方案2】:

    C 中的字符串以空字节('\0' 或 ascii 值 0)终止,这样它就知道字符串在哪里结束。由于偶数和奇数字符数组没有被空字节终止,strcat 不知道何时停止追加字符。所以你看到的垃圾值是因为 strcat 一直在追加字符,直到你幸运地在内存中找到一个 0。

    【讨论】:

      【解决方案3】:

      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);
      

      将 1 加到 message 意味着 copy_every_other_character 将获得指向 message 的第二个字符的指针并从那里继续。如果message01234,它将看到1234

      【讨论】:

      • 除此之外,“C 中的字符串不知道它们的长度,它们只是指针。”将视图 strings 提升为指针,其中 strings 更像 arrays 就像在 'A string is a contiguous sequence以第一个空字符(包括第一个空字符)结尾的字符数。”。
      • @chux 我认为这对于这种理解水平来说太微妙了。我什至不确定你在说什么。重要的是无论你想调用什么,它都必须为空终止。
      猜你喜欢
      • 2022-01-15
      • 2019-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      相关资源
      最近更新 更多