为什么此代码会出现分段错误?

时间:2016-08-06 23:42:56

标签: c

我试图编写一个程序,它接受任意数量的单字文本字符串参数,每个参数少于128个字符。程序将文本从stdin复制到stdout,除了输入中看到的任何单词都替换为单词" CENSORED"。

实施例: 我有一个名为poem.txt的文件:

Said Hamlet to Ophelia,
I'll draw a sketch of thee,
What kind of pencil shall I use?
2B or not 2B? 

该计划应该这样做:

./censor Ophelia < poem.txt
Said Hamlet to CENSORED,
I'll draw a sketch of thee,
What kind of pencil shall I use?
2B or not 2B? 

这是我的代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    char lines[200][200];
    int numLines=0,i,j;
    int nbytes = 128;
    int bytes_read=0;
    char *my_string;
    char * pch;
    //reading from stdin
    while(stdin)
    {
    my_string=(char *) malloc (nbytes + 1);
    bytes_read = getline (&my_string, &nbytes, stdin);  
    strcpy(lines[numLines++],my_string);
    }

    //scanning and replacing specified words by "CENSORED"
    for(i=0;i<argc;i++)
    {
        for(j=0;j<numLines;j++)
        {   
             pch = strstr (lines[j],argv[i]);
             strncpy (pch,"CENSORED",8);
        }
    }
    //display the result in output screen
    for(j=0;j<numLines;j++)
        {
            printf("\n%s",lines[i]);
        }

}

问题在于这会给出分段错误,但我无法识别错误。

1 个答案:

答案 0 :(得分:2)

您没有正确覆盖替换的匹配,可能更长或更短 - 您只是填充它(可能会覆盖终端\0,可能导致您的分段错误)。此外,您似乎错过了双击,因为您只对每行检查每个命令行一次。最后,你通过存储所有行来使这变得更复杂 - 没有任何行会影响任何其他行,那么为什么要存储它们而不是依次处理和打印每一行呢?

这是一个整体简化的方法,更详细的替换代码:

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

#define REPLACEMENT "CENSORED"
#define BUFFER_SIZE (1024)

int main(int argc, char *argv[])
{
    ssize_t bytes_read;
    char *s, *line = malloc(BUFFER_SIZE);
    size_t nbytes = BUFFER_SIZE, replacement_length = strlen(REPLACEMENT);

    // read from stdin
    while ((bytes_read = getline(&line, &nbytes, stdin)) != -1)
    {  
        // scanning and replacing specified words
        for (int i = 1; i < argc; i++)
        {
            while ((s = strstr(line, argv[i])) != NULL)
            {
                size_t search_length = strlen(argv[i]);
                size_t tail_length = strlen(s + search_length);

                (void) memmove(s + replacement_length, s + search_length, tail_length + 1);
                (void) memcpy(s, REPLACEMENT, replacement_length);
            }
        }

        // display the result in output screen
        (void) fputs(line, stdout);
    }

    free(line);
}

哦,是的,你忘了免费 malloc'd 。而且您正在搜索该计划的名称作为您的目标之一......

示例

> ./a.out pencil 2B < poem.txt
Said Hamlet to Ophelia,
I'll draw a sketch of thee,
What kind of CENSORED shall I use?
CENSORED or not CENSORED?