簡體   English   中英

為什么此代碼會導致分段錯誤?

[英]Why is this code giving segmentation fault?

我正在嘗試編寫一個程序,該程序接受任意數量的單字文本字符串參數,每個參數的長度小於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]);
        }

}

問題是這給了細分錯誤,但我無法確定錯誤。

您沒有正確地替換可能更長或更短的替換匹配-您只是將其填充(無論是否覆蓋終端\\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);
}

哦,是的,您忘記釋放分配的內容 您正在搜索程序名稱作為目標之一...

> ./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?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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