从C中的句子中查找缩略语

时间:2018-03-27 03:41:01

标签: c

The assignment

以下是我到目前为止的情况。它并不多,而且可能不正确,所以任何帮助都会受到赞赏。

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

int main()
{
    char word[1000]; 
    char output[1000];
    int n = 50;
    int i, j;

    printf("Please enter a sentence no larger than 1000 characters: ");
    for(i = 0, i < n, i++)
        scanf("%s", &word[i]);

    int length = strlen(word);
    for(i = 0, i < length, i++) {
        if (length <= 4)
        else
        if(word[i] >= 'A' && word[i] <= 'Z') {
            output[i] = word[i];
        }  
    }
    return 0;
}

3 个答案:

答案 0 :(得分:2)

从作业中提取一些提示,指导您指导教师的方向始终是一个好主意。通过阅读,3)似乎您的教师希望您使用strtokstrcmp来识别作业中给出的首字母缩略词(strcpy是多余的,除非您要复制将单词转换为单独的缓冲区 - 不需要生成赋值所需的"Output:"

您还要使用read_line函数来阅读"Input:",但由于这是未提供的内容,我们将不得不假设它会读取一行文字1000个字符或更少(包括 nul-terminatedating 字符)到固定缓冲区(因为没有提到动态分配存储)。

接下来,您将获得一个分隔符列表,用于将单词(标记)与输入行分开。系统会告诉您"white spaces, comma, period and exclamation point"(我们会假设"white spaces"包含space, tab, newline,忽略垂直制表符,因为它在今天非常罕见。您可以在字符串中指定分隔符以传递给{{1 as:

strtok

const char *delim = " \t\n,.!"; 在某种程度上是一种形式,因为字符串文字声明为const是在可执行文件的char *foo = "stuff";部分内创建的并且是不可变的

您还可以将首字母缩略词列表声明为字符串文字,用于初始化指向.rodata的指针数组(const char*再次成为上述形式),例如< / p>

const

然后,要确定 const char *acronyms[] = { "TBH", "BRB", "LOL", "IDK", "TTYL", "IRL", "TIA", "AFK", "CYA", "FYI", "OMG" }; 中包含的首字母缩略词的数量,您可以将acronyms[]除以sizeof acronyms,例如sizeof an_element(或sizeof *arcronyms,您的选择),例如

sizeof acronyms[0]

接下来需要提示输入并使用 size_t n = sizeof acronyms / sizeof *acronyms; /* number acronyms */ 读取输入到至少read_line个字符的缓冲区(比如char line[1000] = "";)。然后,您可以使用1000从行中提取每个单词(标记),其中提取的每个单词将由字符串strtok中包含的一个或多个分隔符分隔。使用delim时,第一次调用使用缓冲区的引用(指针)作为第一个参数。 strtok将返回指向提取的单词的指针(如果没有提取单词,则返回NULL)这里使用简单的指针strtok指向char *p;的返回,例如

strtok

虽然 puts ("Output:"); p = strtok (line, delim); /* 1st call to strtok uses line */ 不是p,但您可以循环,检查NULL指向的令牌对p中的每个首字母缩写,例如

acronyms

注意:在首次使用 while (p != NULL) { /* while p not NULL */ size_t i; /* loop variable */ for (i = 0; i < n; i++) { /* loop over each acronym */ if (strcmp (p, acronyms[i]) == 0) { /* does it match? */ printf ("%s\n", p); /* print it */ break; /* get next word */ } } p = strtok (NULL, delim); /* remaining calls use NULL */ } 而不是strtok之后调用NULL以提取剩余的令牌。)

这非常公正地解读了教师的需求。没有必要花费任何令牌的长度,也没有任何令人信服的理由将检查的令牌数量限制为line(因为您只需将令牌提取到500字符输入的末尾。您可以将500 1000I分隔开,加上行中包含的 nul-terminatedating 字符。无论您是否要添加,我都会留给您完成时有点不可能的限制。

完全放上上述内容并发明一个合理的a,你可以做类似以下的事情:

read_line

示例使用/输出

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

#define MAXC 1000   /*   if you need constants, define them   */
                    /* (don't put magic numbers in your code) */

char *read_line (char *line, size_t max, FILE* fp)
{
    if (fgets (line, max, fp)) {
        size_t len = strlen (line);
        if (len && line[len-1] == '\n')
            line[--len] = 0;
        else
            fprintf (stderr, "warning: characters may remain unread.\n");
        return line;
    }
    return NULL;
}

int main (void)
{
    const char *acronyms[] = { "TBH", "BRB", "LOL", "IDK", "TTYL", "IRL",
                                "TIA", "AFK", "CYA", "FYI", "OMG" },
        *delim = " \t\n,.!";    /* delimiters for strtok */
    char line[MAXC] = "",   /* initialize strings all zero */
        *p = NULL;          /* initialize pointers NULL */
    size_t n = sizeof acronyms / sizeof *acronyms;  /* number acronyms */

    printf ("Input [%d character max]: ", MAXC);    /* prompt */
    if (read_line (line, MAXC, stdin) == NULL) {    /* read/validate line */
        fprintf (stderr, "error: invalid input.\n");
        return 1;
    }

    puts ("Output:");
    p = strtok (line, delim);   /* 1st call to strtok uses line */
    while (p != NULL) {         /* while p not NULL */
        size_t i;               /* loop variable */
        for (i = 0; i < n; i++) {   /* loop over each acronym */
            if (strcmp (p, acronyms[i]) == 0) { /* does it match? */
                printf ("%s\n", p); /* print it */
                break;          /* get next word */
            }
        }
        p = strtok (NULL, delim);   /* remaining calls use NULL */
    }

    return 0;
}

仔细看看,如果您有其他问题,请告诉我。这不是唯一的方法 - 只是最接近教师提示的提示。如果你喜欢随意选择首字母缩略词,你可以一次循环输入一个字符。有很多方法可以做到这一点。

答案 1 :(得分:1)

首先:已经给出了首字母缩略词,所以请将它们保存在一个数组中 :从用户读取一个句子(使用自定义getline函数,它是安全的) 第三次:循环显示您的首字母缩略词,检查该句号是​​否存在于strstr函数的句子中。如果是,请打印该首字母缩略词,然后转到下一个缩写词。

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

char* my_getline()
{
    char * line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c;

    if(line == NULL)
        return NULL;

    for(;;) {
        c = fgetc(stdin);
        if(c == EOF)
            break;

        if(--len == 0) {
            len = lenmax;
            char * linen = realloc(linep, lenmax *= 2);

            if(linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + (line - linep);
            linep = linen;
        }

        if((*line++ = c) == '\n')
            break;
    }
    *line = '\0';
    return linep;
}

int main()
{
    char *acronymz[] = {"TBH", "BRB", "LOL", "IDK", "TTYL", "IRL", "TIA", "AFK", "CYA", "FYI", "OMG"};
    char *sentence1;

    printf("Please enter a sentence no larger than 1000 characters: ");
    sentence1 = my_getline();

    for(int i=0; i<11; i++) {
        if(strstr(sentence1, acronymz[i]) != NULL) {
            printf("%s\n", acronymz[i]);
        }
    }

    return 0;
}

答案 2 :(得分:1)

要实现的一个关键点是无需将整个输入保留在内存中。只需要一个最长的首字母缩写词。

此外,由于首字母缩写词的列表是事先知道的,所以该程序是DFA

因此,无需使用read_linestrtok及相关功能。

请注意,赋值正在尝试让您习惯于C字符串函数;但是,在这种情况下,使用它们远非最佳解决方案。

如何使用有限的内存编写此程序,同时保持首字母缩略词列表易于更改的示例:

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

#define ARRAYSIZE(x) (int)(sizeof(x)/sizeof(x[0]))
#define LONGEST 5

static int issep(int c)
{
    return c == ' ' || c == '.' || c == ',' || c == '!';
}

int main()
{
    static const char s[][LONGEST] = {
        "TBH",  "BRB",  "LOL",  "IDK", "TTYL", "IRL",
        "TIA",  "AFK",  "CYA",  "FYI", "OMG",
    };

    char sc[ARRAYSIZE(s)];
    char b[LONGEST];
    int word = -1;
    int c = 0;
    int i;

    memset(sc, 0, sizeof(sc));

    for (;;) {
        if (c == '\n')
            break;

        c = getchar();

        if (word == -1) {
            if (issep(c))
                continue;

            if (c == '\n')
                break;

            word = 0;
        }

        if (word >= 0) {
            if (c != '\n' && !issep(c)) {
                if (word >= LONGEST)
                    continue;

                b[word] = c;
                ++word;
                continue;
            }

            if (word >= LONGEST) {
                word = -1;
                continue;
            }

            for (i = 0; i < ARRAYSIZE(s); ++i) {
                if (sc[i])
                    continue;

                if (memcmp(s[i], b, word) == 0)
                    sc[i] = 1;
            }

            word = -1;
        }
    }

    for (i = 0; i < ARRAYSIZE(s); ++i)
        if (sc[i])
            puts(s[i]);

    return 0;
}