Как исправить код, который извлекает четные значения индекса в массиве предложения и объединяет его с нечетными значениями индекса? - PullRequest
0 голосов
/ 23 марта 2019

По сути, мой код должен шифровать предложение (или слово), убирая все значения индекса с четным номером (начиная с 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, чтобы протестировать его последние несколько раз, поэтому мои результаты основаны на этом.

Успешный результат:

Successful Result

Неудачный результат с использованием той же записи:

Unsuccessful Result using the same entry

Ответы [ 3 ]

1 голос
/ 23 марта 2019

Вы можете воспользоваться несколько более коротким подходом, просто используя два индекса для построения вашей зашифрованной строки (например, evenstart и oddstart), основываясь на общей длине message, введенной пользователем. 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 & 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'

Посмотрите вещи и дайте мне знать, если у вас есть вопросы.

1 голос
/ 23 марта 2019

Строки в C завершаются нулевым байтом ('\ 0' или значением 0 ascii), чтобы он знал, где заканчивается строка. Поскольку массивы четных и нечетных символов не заканчивались нулевым байтом, strcat не знает, когда прекратить добавление символов. Таким образом, значения мусора, которые вы видите, связаны с тем, что strcat продолжает добавлять символы, пока, к счастью, вы не найдете 0 в памяти.

0 голосов
/ 23 марта 2019

Строки в C не знают своей длины, они просто указатели. Строки должны заканчиваться нулевым символом, чтобы такие функции, как printf и strlen знали, когда следует остановиться.

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

На данный момент even и odd оба содержат любой мусор, который был в памяти в то время.

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

Теперь начало odd и even заполнено, но они не были завершены нулем.

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

Они начнутся там, где указывают even и odd, напечатают введенные вами символы, а затем продолжат печатать любой мусор, который был в памяти, до тех пор, пока они не попадут в нулевой символ.


Исправлено либо обнуление памяти с помощью memset.

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

Или убедитесь, что even и odd завершены нулем, как только вы закончите с ними.

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

Примечание: петли even и odd могут быть выполнены одним и тем же методом.

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. Это означает, что мы можем поместить это в функцию и всегда помнить, что нулевое завершение результата.

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 и продолжит оттуда. Если message равно 01234, он увидит 1234.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...