简体   繁体   English

C 打印最长的单词

[英]C print longest word

I wrote this program to find and print out the longest word (continuous string of [a-zA-Z] characters), where the string is user input.我编写了这个程序来查找并打印出最长的单词( [a-zA-Z]字符的连续字符串),其中字符串是用户输入。 The code works but does have a bug, If I input any special characters like '!'该代码有效但确实有一个错误,如果我输入任何特殊字符,如“!” the output will print out the longest word along with some other weird characters.输出将打印出最长的单词以及其他一些奇怪的字符。 If I do not enter any special characters the program works as intended.如果我不输入任何特殊字符,程序将按预期工作。 I am sure this is something simple, but I haven't been able to figure out what is causing this bug.我确信这很简单,但我一直无法弄清楚是什么导致了这个错误。 Also any methods of improving the code would be appreciated.任何改进代码的方法也将不胜感激。

Thank you all for your time.谢谢大家的时间。

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

The problems are:问题是:

  • temp_string and longest_string should be defined with a size of input_length + 1` temp_string和longest_string should be defined with a size of input_length + 1`
  • you should set longest_string to an empty string with *longest_string = '\\0';您应该使用*longest_string = '\\0';longest_string设置为空字符串*longest_string = '\\0'; to avoid printing an uninitialized array if there are no letters on the line.如果行上没有字母,则避免打印未初始化的数组。
  • avoid hardcoding ASCII values in your code, it is not readable.避免在代码中硬编码 ASCII 值,因为它不可读。 You could use (sen[i] >= 'a' && sen[i] <= 'z') || (sen[i] >= 'A' && sen[i] <= 'Z')你可以使用(sen[i] >= 'a' && sen[i] <= 'z') || (sen[i] >= 'A' && sen[i] <= 'Z') (sen[i] >= 'a' && sen[i] <= 'z') || (sen[i] >= 'A' && sen[i] <= 'Z') or better use isalpha((unsigned char)sen[i]) from <ctype.h> . (sen[i] >= 'a' && sen[i] <= 'z') || (sen[i] >= 'A' && sen[i] <= 'Z')或者更好地使用来自<ctype.h> isalpha((unsigned char)sen[i])
  • you only test for the longest string if you find a byte that is not a letter.如果找到不是字母的字节,则仅测试最长的字符串。 This prevents the last word from being included in the search.这可以防止搜索中包含最后一个单词。 You should instead first find a letter, then match all subsequent letters and test if you have found a longer word.您应该首先找到一个字母,然后匹配所有后续字母并测试您是否找到了更长的单词。
  • the calls to memset are overkill.memset的调用太过分了。 You should just set the null terminator in temp_string with temp_string[current_len] = '\\0';您应该使用temp_string[current_len] = '\\0';temp_string设置空终止符temp_string[current_len] = '\\0'; so strcpy can copy it as a C string and get rid of both memset calls.所以strcpy可以将它复制为 C 字符串并摆脱两个memset调用。

You don't actually need to copy the substrings, just keep track of the offsets for the current and longest word:您实际上不需要复制子字符串,只需跟踪当前单词和最长单词的偏移量:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM