簡體   English   中英

多個命令行參數-替換單詞

[英]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單詞的順序,您仍然難以解析單詞。

盡管可以執行指針算術來復制/擴展/壓縮原始字符串,而不管單詞在命令行上出現的順序如何,但將提供的單詞簡單地分成一個數組,然后比較每個單詞要容易得多。反對原始字符串中每個單詞的壞單詞。

這可以通過strtokstrsep相對容易地實現。 我整理了一個簡單的示例來說明這種方法。 請注意:在傳遞給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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM