C печатать самое длинное слово - PullRequest
1 голос
/ 02 мая 2019

Я написал эту программу, чтобы найти и распечатать самое длинное слово (непрерывная строка из [a-zA-Z] символов), где строка является вводом пользователем.Код работает, но есть ошибка, если я введу какие-либо специальные символы, такие как '!'вывод выведет самое длинное слово вместе с некоторыми другими странными символами.Если я не буду вводить какие-либо специальные символы, программа будет работать так, как задумано.Я уверен, что это что-то простое, но я не смог понять, что является причиной этой ошибки.Также приветствуются любые методы улучшения кода.

Спасибо всем за потраченное время.

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

#define MAX_INPUT 1000

void LongestWord(char sen[]);

int main(void) {
  char input[MAX_INPUT];

  LongestWord(fgets(input, MAX_INPUT, stdin));
  return 0;
}

void LongestWord(char sen[]) {
    int i, current_len, longest_len, input_length;

    input_length = strlen(sen);

    char temp_string[input_length];
    char longest_string[input_length];

    current_len = longest_len = 0;

    for (i = 0; i < input_length; i++) {
        //If it is a letter
        if ((sen[i] >= 97 && sen[i] <= 122) || (sen[i] >= 65 && sen[i] <= 90)) {
            temp_string[current_len] = sen[i];
            current_len++;
        } else {
            if (current_len > longest_len) {
                //Clear longest string
                memset(longest_string, 0, sizeof(longest_string));

                //Copy temp_string to longest string
                strcpy(longest_string, temp_string);

                //set longest length equal to current
                longest_len = current_len;

                //Clear temp_string
                memset(temp_string, 0, sizeof(temp_string));
            }
            current_len = 0;
        }
    }

    printf("Longest string: %s\n", longest_string);
}

1 Ответ

1 голос
/ 06 мая 2019

Проблемы:

  • temp_string и longest_string should be defined with a size of input_length + 1`
  • Вы должны установить longest_string в пустую строку с *longest_string = '\0';, чтобы избежать печати неинициализированного массива, если в строке нет букв.
  • избегайте жесткого кодирования значений ASCII в вашем коде, он не читается. Вы можете использовать (sen[i] >= 'a' && sen[i] <= 'z') || (sen[i] >= 'A' && sen[i] <= 'Z') или лучше использовать isalpha((unsigned char)sen[i]) из <ctype.h>.
  • вы проверяете только самую длинную строку, если найдете байт, который не является буквой. Это предотвращает включение последнего слова в поиск. Вместо этого сначала нужно найти букву, затем сопоставить все последующие буквы и проверить, не нашли ли вы более длинное слово.
  • звонки на memset излишни. Вы должны просто установить нулевой терминатор в temp_string с помощью temp_string[current_len] = '\0';, чтобы strcpy мог скопировать его как строку C и избавиться от обоих вызовов memset.

На самом деле вам не нужно копировать подстроки, просто следите за смещениями для текущего и самого длинного слова:

#include <ctype.h>
#include <stdio.h>

void LongestWord(const char *sen) {
    int i, len, best_start, best_len;

    best_start = best_len = 0;
    for (i = 0; sen[i] != '\0'; i++) {
        if (isalpha((unsigned char)sen[i]) {
            // we have a letter: compute the word length
            for (len = 1; isalpha((unsigned char)sen[i + len]; len++)
                continue;
            if (len > best_len) {
                // remember the longest word's offset and length
                best_start = i;
                best_len = len;
            }
            // skip all letters (-1 because of i++ in the for loop)
            i += len - 1;
        }
    }
    // use `%.*s` to print a substring with printf
    printf("Longest string: %.*s\n", best_len, sen + best_start);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...