0

数日前に C でプログラミングを始めたばかりです。私のプログラムはファイルを開き、それを1行ずつ読み取り、不要なもの(括弧、改行など)を削除します。次に、データをコンマ区切り形式で取得したら、それを配列に追加します(次に、その配列を配列の配列に追加します)。コンマ区切りの文字列をトークン化するところまで来EXC_BAD_ACCESS, Could not access memory.ましたが、デバッガーで実行すると取得し続けます。

私は何を間違っていますか?問題を引き起こしているコードのセクションは次のとおりです。

//now data(variable: line) looks like this:  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
char *str_ptr;
str_ptr = strtok(line, ",");
  for(; str_ptr != NULL ;){
    fprintf(stdout, "%s\n", str_ptr);
    str_ptr = strtok(NULL, ",");
  }

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

#include <stdio.h>

int main() {

    char line[1024];
    FILE *fp = fopen("/Users/me/Desktop/output.txt","r");

    printf("Starting.. \n");
    if( fp == NULL ) {
        return 1;
    }
    int count = 0;
    int list[30]; //items will be stored here

    while(fgets(line, 1024, fp) != EOF) {
        count++;
        //parse the text in the line Remove the open bracket, then remove the last newline,comma and close bracket
        // data looks like this: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4],
        size_t len = strlen(line);
        memmove(line, line+1, len-4);
        line[len-4] = 0;
        printf("%s \n",line);

        //parse the numbers in the char
        //now data looks like this:  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
        char *str_ptr;
        str_ptr = strtok(line, ",");
          for(; str_ptr != NULL ;){
            fprintf(stdout, "%s\n", str_ptr);
            str_ptr = strtok(NULL, ",");
          }


        //for testing just stop the file after two lines
        if (count == 2) {
            break;
        }

        
        if ( count > 1000000) {
            printf("count is higher than 1,000,000 \n");
            count = 0;
        }
    }
    printf(" num of lines is %i \n", count);

    return 0;
}

この場合、デバッガー以外に意味のある情報を取得する方法がわかりません。

アップデート

申し訳ありませんが、これを行う方法がわかりませんでした。これはデバッガーのスタックのコピーです(メイン以外、それらをクリックすると、すべて「..のソースがありません」と表示され、リストの項目が表示されます:

Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)    
    strlen() at 0x7fff875ef4f0  
    __vfprintf() at 0x7fff875908c3  
    vfprintf_l() at 0x7fff8758f18e  
    fprintf() at 0x7fff87598d9a 
    main() at learningC.c:77 0x100000d5a    
4

2 に答える 2

1

入力ファイルが常に有効であれば、何も問題はありません。私はそれを自分のMacでコンパイルして実行しようとしましたが、それは本当にうまく機能しています。おそらく、サンプルファイルをどこかにアップロードして、何が起こっているのかを正確に確認できます。これは、コードのmemmove一部が無効な入力(空白行や短い行など)に対して脆弱すぎるためです。に変更することをお勧めします

char* data = line;
size_t len = strlen(line);
if (len > 3) {
    line[len - 3] = '\0';
    data++;
}

char *str_ptr;
str_ptr = strtok(data, ",");
for(; str_ptr != NULL ;){
    fprintf(stdout, "%s\n", str_ptr);
    str_ptr = strtok(NULL, ",");
}

私のコードはまだ完全なデータ検証にはほど遠いですが、少なくとも空白行にセグメンテーション違反をスローすることはありません。

于 2012-06-01T02:16:41.123 に答える
1

fgetsNULLエラーまたは EOF を返します。ではないことを確認してくださいEOF

while(fgets(line, 1024, fp) != NULL){
于 2012-05-31T16:43:10.487 に答える