以下是我到目前为止的情况。它并不多,而且可能不正确,所以任何帮助都会受到赞赏。
#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;
}
答案 0 :(得分:2)
从作业中提取一些提示,指导您指导教师的方向始终是一个好主意。通过阅读,3)
似乎您的教师希望您使用strtok
和strcmp
来识别作业中给出的首字母缩略词(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 1000
或I
分隔开,加上行中包含的 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_line
,strtok
及相关功能。
请注意,赋值正在尝试让您习惯于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;
}