[英]Multiple Command-Line Arguments - Replace Words
我有一个程序可以从命令行参数中提取任意数量的单词,并将其替换为“ CENSORED”一词。 我终于让程序可以处理传入的第一个参数,而且我很难让程序检查仅在单个字符串中输出的所有参数。 该程序宁可根据给定参数单独运行,也不会考虑所有因素。 我将如何修改呢?
一个人如何集体使用/操纵多个命令行参数?
我的代码如下。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *replace_str(char *str, char *orig, char *rep, int j, int argc)
{
static char buffer[4096];
char *p;
for ( j = 1; j <= argc; j++ )
{
if(!(p = strstr(str, orig))) // Check if 'orig' is not in 'str'
{
if ( j == argc ) { return str; } // return str once final argument is reached
else { continue; } // restart loop with next argument
}
strncpy(buffer, str, p-str); // Copy characters from 'str' start to 'orig' str
buffer[p-str] = '\0';
if ( j == argc ) { return buffer; }
else { continue; }
}
sprintf(buffer+(p-str), "%s%s", rep, p+strlen(orig));
}
int main( int argc, char* argv[] ) //argv: list of arguments; array of char pointers //argc: # of arguments.
{
long unsigned int c, i = 0, j = 1;
char str[4096];
while ( (c = getchar()) != EOF )
{
str[i] = c; // save input string to variable 'str'
i++;
}
puts(replace_str( str, argv[j], "CENSORED", j, argc ) );
return 0;
}
i.e.
$ cat Hello.txt
Hello, I am me.
$ ./replace Hello me < Hello.txt
CENSORED, I am CENSORED.
有两个问题,您不能保证以null结尾的str
,第二个问题是,您不能在命令行上的单词上进行迭代以检查每个单词。 在您的getchar()
循环之后,在main中尝试以下操作:
/* null-terminate str */
str[i] = 0;
/* you must check each command line word (i.e. argv[j]) */
for (j = 1; j < argc; j++)
{
puts(replace_str( str, argv[j], "CENSORED", j, argc ) );
}
注意:这会将每个CENSORED单词放在单独的行上。 如注释中所述,将puts
(或最好是printf
)移到循环外以保持一行。
编辑
我道歉。 您遇到的问题比上述更多。 尝试检查此修复程序时,很显然,根据在命令行上输入bad
单词的顺序,您仍然难以解析单词。
尽管可以执行指针算术来复制/扩展/压缩原始字符串,而不管单词在命令行上出现的顺序如何,但将提供的单词简单地分成一个数组,然后比较每个单词要容易得多。反对原始字符串中每个单词的坏单词。
这可以通过strtok
或strsep
相对容易地实现。 我整理了一个简单的示例来说明这种方法。 ( 请注意:在传递给strtok
之前,请先复制字符串,因为这会更改原始字符串)。 我相信这是您正在尝试做的事情,但是您因无法比较每个单词而绊绊(因此您使用strstr
来测试匹配项)。
查看示例,让我知道是否还有其他问题。 注意:我用SMAX
定义替换了您的硬编码4096
,并为在命令行上输入的单词提供了单词max WMAX
。 还请务必初始化您的字符串/缓冲区 。 这将使您始终能够轻松找到缓冲区中的最后一个字符,并确保缓冲区始终为空终止。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SMAX 4096
#define WMAX 50
char *replace_str (char *str, char **bad, char *rep)
{
static char buffer[SMAX] = {0};
char *p = buffer;
char *wp = NULL;
unsigned i = 0;
unsigned char censored = 0;
char *str2 = strdup (str); /* make copy of string for strtok */
char *savp = str2; /* and save start address to free */
if (!(wp = strtok (str2, " "))) /* get first word in string or bail */
{
if (savp) free (savp);
return str;
}
while (bad[i]) /* test against each bad word */
{
if (strcmp (wp, bad[i++]) == 0) /* if matched, copy rep to buffer */
{
memcpy (buffer, rep, strlen (rep));
censored = 1;
}
}
if (!censored) /* if no match, copy original word */
memcpy (buffer, wp, strlen (wp));
while ((wp = strtok (NULL, " "))) /* repeat for each word in str */
{
i = 0;
censored = 0;
memcpy (strchr (buffer, 0), " ", 1);
p = strchr (buffer, 0); /* (get address of null-term char) */
while (bad[i])
{
if (strcmp (wp, bad[i++]) == 0)
{
memcpy (p, rep, strlen (rep));
censored = 1;
}
}
if (!censored)
memcpy (p, wp, strlen (wp));
}
if (savp) free (savp); /* free copy of strtok string */
return buffer;
}
int main ( int argc, char** argv)
{
unsigned int i = 0;
char str[SMAX] = {0};
char *badwords[WMAX] = {0}; /* array to hold command line words */
for (i = 1; i < argc; i++) /* save command line in array */
badwords[i-1] = strdup (argv[i]);
i = 0; /* print out the censored words */
printf ("\nCensor words:");
while (badwords[i])
printf (" %s", badwords[i++]);
printf ("\n\n");
printf ("Enter string: "); /* promt to enter string to censor */
if (fgets (str, SMAX-1, stdin) == NULL)
{
fprintf (stderr, "error: failed to read str from stdin\n");
return 1;
}
str[strlen (str) - 1] = 0; /* strip linefeed from input str */
/* print out censored string */
printf ("\ncensored str: %s\n\n", replace_str (str, badwords, "CENSORED"));
i = 0; /* free all allocated memory */
while (badwords[i])
free (badwords[i++]);
return 0;
}
使用/输出
./bin/censorw bad realbad
Censor words: bad realbad
Enter string: It is not nice to say bad or realbad words.
censored str: It is not nice to say CENSORED or CENSORED words.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.