0

明らかな理由もなく、セグメンテーション違反が発生しています。関数を使用して、strtok各行を複数のトークンに分割し、char ポインターに格納しています。私のデータは次のようになります。

入力:

200 -> 103 [weight=7];
200 -> 153 [weight=27];
200 -> 53 [weight=9];
200 -> 178 [weight=43];
55 -> 2 [weight=23];
55 -> 14 [weight=50];
55 -> 20 [weight=17];
55 -> 22 [weight=1];
55 -> 74 [weight=7];
55 -> 93 [weight=9];
55 -> 122 [weight=27];
65 -> 8 [weight=27];
65 -> 9 [weight=9];

コード:

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

int main(int argc,char **argv)
{
        char *ipfile,line[80];
        FILE *fp;
        char *field1,*field2,*field3,*field4,*field5,*field6,mystr[10];
        int row,column,weight;
        ipfile = (char *)argv[1];
        printf("The input file name is %s\n",ipfile);
        fp = fopen(ipfile,"r");

        if(fp ==NULL) //Checking whether the command line argument was correctly or not.
        printf("There is no such file in the directory.\n");

        while(fgets(line,80,fp) != NULL)
        {
                field1 = strtok(line," ");
                //row    = atoi(field1);
                field2 = strtok(NULL," ");
                field3 = strtok(NULL," ");
                //column = atoi(field3);
                field4 = strtok(NULL," ");
                field5 = strtok(NULL," ");
                //field6 = strtok(NULL," ");

                printf("%s\n",field5);
                //printf("Row-%d Column - %d Weight - %d\n",row,column,weight);
        }
        fclose(fp);
        return 0;
}

コメントから:

、、、を印刷しようとすると、それらfield1が印刷されます。しかし、試してみると、プログラムがセグメンテーション違反を起こしています。field2field3field4field5field6

SO ユーザーの提案の後にコードを追加します。

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

int main(int argc,char **argv)
{
        char *ipfile,line[80];
        FILE *fp;
        char *field1,*field2,*field3,*field4,*field5,*field6,mystr[10];
        int row,column,weight;
        ipfile = (char *)argv[1];
        printf("The input file name is %s\n",ipfile);
        fp = fopen(ipfile,"r");

        if(fp == NULL) //Checking whether the command line argument was correctly or not.
        printf("There is no such file in the directory.\n");

        while(fgets(line,80,fp) != NULL)
        {
                field1 = strtok(line," ");
                //row    = atoi(field1);
                field2 = strtok(NULL," ");
                field3 = strtok(NULL," ");
                //column = atoi(field3);
                field4 = strtok(NULL," ");
                field5 = strtok(NULL," []=;");
                //field6 = strtok(NULL," ");

                printf("%s\n",field5);
                //printf("Row-%d Column - %d Weight - %d\n",row,column,weight);
        }
        fclose(fp);
        return 0;
}
4

2 に答える 2

7

文字列をスペースで分割しているため、コードでは 6 が必要ですが、これには 4 つのトークンしかありません。

200 -> 103 [weight=7];

" []=;"これを修正するには区切り文字として指定します。(または、->それを行っているときにも含めます。)

于 2012-12-01T22:52:16.963 に答える
2

これを試して:

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

int main(int argc, char **argv)
{
    char line[80];
    char *field1, *field2, *field3, *field4, *field5;
    char *ipfile = argv[1];

    if (argc == 1)
    {
        fprintf(stderr, "Usage: %s file\n", argv[0]);
        return(1);
    }
    printf("The input file name is %s\n", ipfile);
    FILE *fp = fopen(ipfile, "r");

    if (fp == NULL) //Checking whether the command line argument was correctly or not.
    {
        fprintf(stderr, "There is no such file in the directory.\n");
        return(1);
    }

    char const *delim = " [];=";
    while (fgets(line, sizeof(line), fp) != NULL)
    {
        printf("Input: %s", line);
        field1 = strtok(line, delim);
        //row    = atoi(field1);
        field2 = strtok(NULL, delim);
        field3 = strtok(NULL, delim);
        //column = atoi(field3);
        field4 = strtok(NULL, delim);
        field5 = strtok(NULL, delim);
        //field6 = strtok(NULL, delim); 
        printf("Field 1: %s\n", field1);
        printf("Field 2: %s\n", field2);
        printf("Field 3: %s\n", field3);
        printf("Field 4: %s\n", field4);
        printf("Field 5: %s\n", field5);
        //printf("Row-%d Column - %d Weight - %d\n", row, column, weight);
    }
    fclose(fp);
    return 0;
}

あなたのデータ(ファイルに保存されているstrtok.data)では、次の結果が得られます。

The input file name is strtok.data
Input: 200 -> 103 [weight=7];
Field 1: 200
Field 2: ->
Field 3: 103
Field 4: weight
Field 5: 7
Input: 200 -> 153 [weight=27];
Field 1: 200
Field 2: ->
Field 3: 153
Field 4: weight
Field 5: 27
Input: 200 -> 53 [weight=9];
Field 1: 200
Field 2: ->
Field 3: 53
Field 4: weight
Field 5: 9
Input: 200 -> 178 [weight=43];
Field 1: 200
Field 2: ->
Field 3: 178
Field 4: weight
Field 5: 43
Input: 55 -> 2 [weight=23];
Field 1: 55
Field 2: ->
Field 3: 2
Field 4: weight
Field 5: 23
Input: 55 -> 14 [weight=50];
Field 1: 55
Field 2: ->
Field 3: 14
Field 4: weight
Field 5: 50
Input: 55 -> 20 [weight=17];
Field 1: 55
Field 2: ->
Field 3: 20
Field 4: weight
Field 5: 17
Input: 55 -> 22 [weight=1];
Field 1: 55
Field 2: ->
Field 3: 22
Field 4: weight
Field 5: 1
Input: 55 -> 74 [weight=7];
Field 1: 55
Field 2: ->
Field 3: 74
Field 4: weight
Field 5: 7
Input: 55 -> 93 [weight=9];
Field 1: 55
Field 2: ->
Field 3: 93
Field 4: weight
Field 5: 9
Input: 55 -> 122 [weight=27];
Field 1: 55
Field 2: ->
Field 3: 122
Field 4: weight
Field 5: 27
Input: 65 -> 8 [weight=27];
Field 1: 65
Field 2: ->
Field 3: 8
Field 4: weight
Field 5: 27
Input: 65 -> 9 [weight=9];
Field 1: 65
Field 2: ->
Field 3: 9
Field 4: weight
Field 5: 9

問題が発生した場合は、印刷してください。入力行を印刷して、自分が読んでいると思っているものを読んでいることを確認してください。取得した値を出力します。seg fault の問題がある場合は、null ポインターの出力に注意してください。一部の C ライブラリは (あまりにも) 親切で<null>、null 文字列を出力しようとすると出力するか、似たようなものです。他はクラッシュします。幸運ですね; クラッシュするものがあるので、いつそれが間違っているかを知ることができます。からの戻り値をチェックするコードは追加しませんでしたstrtok()。それが私のコードであり、私が使用していた場合strtok()—これはあまりありそうにありません。私は好きではありませんstrtok()— 再試行する前に、各フィールドが null でないことを確認します。個別に名前を付けた変数の代わりに、配列とループを使用することもあるでしょう。

于 2012-12-01T23:21:24.850 に答える