0

だから私は、テキスト文書の行を単一の単語でスキャンする方法を理解しようとしています。キーワードはテキスト ファイルから取得され、構造体に格納されます。同じファイルには、そのキーワードをスキャンするファイルをスキャンするためのディレクトリも含まれています。私のプログラムは、要求ファイルから読み取り、指定されたディレクトリを開くことができます。また、そこにあるファイルを確認することもできます。この時点で、ファイルをスキャンしてユーザーに出力しようとしている最中に SegFault でエラーが発生します。どんな助けでも大歓迎です。

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <dirent.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/types.h>

/* Structs */
struct input
{
    char match[6];
    char path[100];
    char key[20];
};

/* Variables */
//char match[6];
//char path[100];
//char key[20];
int last = 0;
int linen = 1;
char filename[100];
char top[256];
int x = 0;
static int MAXLINESIZE = 1000;
static int MAXDIRNAME = 200;
static int MAXKEYWORD = 1000;

struct input insave[50];

/* Prototypes */
void readfile();
void readtdir();
void scanfile();

/* Methods */
//Scan directory in in.txt file for text files to scan
void readtdir()
{
    DIR *dir;
    struct dirent *dirr;
    char temp[256];


    for(x = 0; x < last; x++)
    {
        dir = opendir(insave[x].path);
        strcpy(top, insave[x].path);
        printf("\nOpened: %s\n", insave[x].path);
        //printf("dir: %s\n", top);
        if(dir != NULL)
        {
            while((dirr = readdir(dir)) != NULL)
            {
                if(!(strcmp(dirr->d_name,"..")))
                {
                    continue;
                }
                else
                {
                    if(!(strcmp(dirr->d_name,".")))
                    {
                        continue;
                    }
                    else
                    {
                        printf("%s\n",dirr->d_name);

                        if(dirr->d_type == 8)
                        {
                            sprintf(temp, "%s", dirr->d_name);
                            printf("%s\n", temp);
                            strcpy(filename, temp);
                            scanfile(filename);
                        }
                    }
                }
            }
        }
        closedir(dir);
    }
    return;
}

//Scan lines of individual file for keyword
void scanfile(char *argv)
{
    FILE *fRead;
    char line[MAXLINESIZE];
    char templine[MAXLINESIZE];
    int y = x;

    fRead = fopen(argv, "r+");

    if(fRead == NULL)
    {
        printf("File cannot be opened");
    }
    else
    {
        while(fgets(line,MAXLINESIZE,fRead) != NULL)
        {
            strcpy(templine, line);
            if(strstr(templine,insave[y].key) != NULL)
            {
                printf("%s:%d:%s", filename, linen, line);
            }
            linen++;
        }
    }
    fclose(fRead);
}

//Read in.txt file for commands
void readfile(char *argv)
{
    FILE *pRead;
    int x = 0;
    char match[6];
    char path[100];
    char key[20];

    pRead = fopen(argv, "r+");

    if(pRead == NULL)
    {
        printf("File cannot be opened");
    }
    else
    {
        while(!feof(pRead))
        {
            if(fscanf(pRead, "%5s%99s%19s", match, path, key) != 3)
            {
                break;
            }
            else
            {
                strcpy(insave[x].match, match);
                strcpy(insave[x].path, path);
                strcpy(insave[x].key, key);
                x++;
                last = x;
            }
        }
    }
    fclose(pRead);
}

int main(int argc, char *argv[])
{
    int x = 0;
    argv[1] = "5";   //only used for testing purposes
    argv[2] = "in.txt";   //only used for testing purposes

    readfile(argv[2]);
    readtdir();

    printf("\n\n");
    for(x = 0; x < last; x++)
    {
        printf("This is: %s\n",insave[x].match);
        printf("This is: %s\n",insave[x].path);
        printf("This is: %s\n\n",insave[x].key);
    }
    return 0;
}
4

1 に答える 1

0

いくつかのアイデア:

マジックナンバー100の代わりに

#include <limits.h>
// If NAME_MAX does not exist, try something like 1024 – 100 is small.
// At least during debug
char filename[NAME_MAX + 1];

マジックナンバー256の代わりに

// char temp[256];
struct dirent temp;
…
sprintf(temp.d_name, "%s", dirr->d_name);
printf("%s\n", temp.d_name);
strcpy(filename, temp.d_name);

の必要はありません。char templine[MAXLINESIZE];使用するだけstrstr(line,insave[y].key)です。

main()、 を削除しwhile(!feof(pRead))ます。それは何の役にも立ちません。EOF は、読み取りを試みて何も取得しないまで検出されません。その場合、すでにfscanf()EOF が返されており、 break.

に保険0 <= x < 50をかけinsave[x]ます。

の代わりにif(dirr->d_type == 8)、 を使用しますDT_REG

ないでください

argv[1] = "5";   //only used for testing purposes
argv[2] = "in.txt";

あなたはどれだけ大きいかわからないargv。その代わり:

char *my_argv[4];
my_argv[0] = argv[0];
my_argv[1] = "5";   //only used for testing purposes
my_argv[2] = "in.txt";
my_argv[3] = NULL;
readfile(my_argv[2]);
于 2013-11-11T04:49:14.180 に答える