我的一个朋友给了我一个编写程序的任务
用C中的文本文件中的空格替换“a”,“an”,“the”。
我写了那个程序,但是因为我单独检查了“a”,“an”,“the”这个过程太长了。
例如,我将"a"
替换为
注意:fs
是指向源文件的指针,ft
是指向目标文件的指针。
while(fgets(str, 100, fs) != NULL)
{
for(i = 0; str[i] != '\0'; i++)
{
if (str[i] == ' ' ||
str[i] == '.' ||
str[i] == ',' ||
str[i] == '\n' ||
str[i] == '\t')
{
if (str[i+1] == 'a' || str[i+1] == 'A')
{
if (str[i+2] == ' ' ||
str[i+2] == '.' ||
str[i+2] == ',' ||
str[i+2] == EOF ||
str[i+2] == '\0' ||
str[i+2]== '\n' ||
str[i+2]== '\t')
{
str[i+1]=' ';
}
}
}
}
fputs(str,ft);
}
有没有更短的方法来做同样的事情?
请注意"a"
,"an"
,"the"
可以是源文件中的第一个单词。
答案 0 :(得分:2)
使用fscanf
和fprintf
功能,以便您轻松扫描文件,并轻松检查'a,an,':
char s[50];
while(fscanf(fp, "%s", s) != EOF)
{
if(strcmp(s, "a") == 0 || strcmp(s, "an") == 0 || strcmp(s, "the") == 0)
{
char c = ' ';
fprintf(ft, "%s", c);
}
else
{
fprintf(ft, "%s", s);
}
}
答案 1 :(得分:1)
您可以使用例如getchar读取输入char-by-char,或者始终记住最后几个字符,即使它们位于前一个缓冲区中。这样你需要记住前两个字符,以及一个小的“滚动数组”中的当前字符,你将在每个字边界重置。
使用带有fgets或fscanf的固定大小的缓冲区,您需要大量代码来处理特殊情况。有一些,例如,线条不是以空格或制表符开头,但是线条也可以以“the”开头。在这种情况下,在该词之前将不会有这样的字符。关于单词后面的空格也是如此。您可以通过为缓冲区分配更多空间来解决这些问题,使用''填充第一个字符,并以这种方式调用fgets:
fgets(str + 1, 99, fs)
但你仍然有边界的单词问题,你的缓冲区以“... t”结束,下一个fgets给你“他......”。 只需保留一个由3个字符组成的数组,以及数组的当前长度,在每个字边界处将长度重置为零。
答案 2 :(得分:1)
我认为这段代码适用于问题的合理定义:
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static char const *words[] = { "a", "the", "an" };
enum { NUM_WORDS = sizeof(words) / sizeof(words[0]) };
static void mapword(char *word, int len)
{
char lower[256];
word[len] = '\0';
for (int i = 0; i <= len; i++)
lower[i] = tolower(word[i]);
for (int i = 0; i < NUM_WORDS; i++)
{
if (strcmp(words[i], lower) == 0)
{
putchar(' ');
return;
}
}
fputs(word, stdout);
}
int main(void)
{
char word[256];
int c;
size_t nletters = 0;
while ((c = getchar()) != EOF)
{
/*
** This would break if you enter a word with 256 characters
** ending in 'a' because the word would be split after 255
** characters and the trailing 'a' would then match the
** next buffer full, which is an awfully improbable event.
*/
if (!isalpha(c) || nletters >= sizeof(word)-1)
{
if (nletters > 0)
{
mapword(word, nletters);
nletters = 0;
}
putchar(c);
}
else
word[nletters++] = c;
}
if (nletters > 0)
{
/*
** Since a text file should end with a newline, the program
** should not get here!
*/
mapword(word, nletters);
}
return 0;
}
例如,给出问题的前三行作为输入:
A friend of mine gave me a task to write a program to
replace "a", "an", "the" with blank space in a text file in c.
I wrote that program but that went too lengthy as I checked "a", "an", "the" individually.
程序的输出是:
friend of mine gave me task to write program to
replace " ", " ", " " with blank space in text file in c.
I wrote that program but that went too lengthy as I checked " ", " ", " " individually.
答案 3 :(得分:1)
如果你想使用一些system
命令,那么你的生活很简单。 sed
是linux命令来满足您的要求。
您可以执行以下操作
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
system("sed 's/an//g;s/a//g;s/the//g' file");
}
如果file
包含
replace “a”, “an”, “the” with blank space in a text file
输出
replce “”, “”, “” with blk spce in text file
警告:此代码在找到匹配模式的每个位置都会替换空格。因此,它不会检查匹配的整个单词。