1

ファイル内のテキスト文字列を検索して別の文字列に置き換える小さな C プログラムを作成していますが、これを行っている間にセグメンテーション違反が発生し続け、何らかの理由で fgets 呼び出し後にバッファー (c という名前) が空になります。

ここに私のコードがあります:

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



/*
 *program replaces all strings that match a certain pattern within a file
 */

int main(int argc, char** argv)
{
    // check if there are correct amount of arguments
    if(argc != 4) 
    {
            printf("Error, incorrect amount of input arguments!\n");
            return 1;
    } // end if

    // initializers
    int i;
    char* temp;
    FILE* searchFile;
    char* c = malloc(sizeof(char));
    char* fileName = malloc(sizeof(argv[1]));
    char** searchWord = malloc(sizeof(argv[2]));
    char* replaceWord = malloc(sizeof(argv[3]));

    fileName = argv[1];
    *searchWord = argv[2];
    replaceWord = argv[3];

    // checks to see if searchWord isnt too big
    if(strlen(*searchWord) > 256)
    {
            printf("Error, incorrect amount of input arguments!\n");
            return 1;
    }

    // opens file
    searchFile = fopen(fileName,"r+");

    // searches through file
    do
    {
            fgets(c, 1, searchFile);

            i = 0;
            while(i < strlen(*searchWord))
            {
                    printf("search character number %i: %c\n", i, *searchWord[i]);     

                    /* 
                     * finds number of letters in searchWord 
                     * by incrementing i until it is equal to size of searchWord
                     */
                    if(strcmp(c,searchWord[i])) 
                    {

                            i++;
                    }

                    // replaces searchWord with replace word
                    if(i == (strlen(*searchWord)))
                    {
                            printf("inside replace loop\n");
                            memcpy(searchWord, replaceWord,(sizeof(replaceWord)/sizeof(char))+1);
                            printf("The search term (%s) has been replaced with the term: %s!\n",*searchWord,replaceWord);
                    }
            }
    }while(strlen(c) > 0);

    // closes file
    fclose(searchFile);
}
4

1 に答える 1

1

サイズ 1 を fgets に渡しています。ただし、fgets 関数は、指定されたストリームから size で指定された文字数より最大で 1 つ少ない文字数を読み取ります。したがって、サイズ 1 を渡すと、0 文字が読み取られます。読み取りが 1 つ少ない理由は、null の「行末」文字のためのスペースが残っているためです。

fgets 関数は、改行文字が見つかった場合、ファイルの末尾またはエラー時に読み取りを停止し、改行があれば保持されます。したがって、文字列内にあると予想される文字数に加えて、改行用に1つ、ヌルの「行末」文字用に1つを加えた数になるように、 c をmallocする必要があります。

他に注意すべき点がいくつかあります。次の 2 つのステートメントの最初のステートメントは、最初にファイル名を格納するための領域を割り当て、次にファイル名ポインタをそのファイルに向けます。2 番目は、プログラムへの最初の引数を含む渡された文字列を指すようにファイル名ポインターをポイントします。

char* fileName = malloc(sizeof(argv[1]));
fileName = argv[1];

ファイル名ポインタをそこに直接向けて、メモリを割り当てないでください。

char* fileName = argv[1];

または、実際に割り当てられたメモリが必要な場合は、2 行目を変更して文字列の内容をコピーします。

char* fileName = malloc(sizeof(argv[1]));
strcpy(fileName,argv[1]);

または、さらに簡単に strdup を使用してメモリを割り当て、内容をコピーします。

char* fileName = strdup(argv[1]);
于 2012-10-23T04:17:08.450 に答える