1

私はCに本当に慣れていません(私はCudaを学び、Cを学びたいと思っていたので、Java / Pythonでデータを生成し、それを手動でCudaプログラムにコピーして貼り付けて遊ぶ代わりに、すべてを一緒に実行できます)。大きなファイル(20 + GB)を開いてデータを解析しようとしていますが、問題が発生したため、最初に問題を分析して、ファイルを1行ずつ開いてから、別のファイルで読み取ることができることを確認することにしました。行の出力のサンプルを取り、それを解析してみてください。すべてがうまくいけば、単純にそれらをまとめることができます。私は(少し苦労して)各パーツを機能させることができましたが、それらを組み合わせると機能しません(EclipseとQTクリエーターの両方で試しました。QTクリエーターは予期せず終了し、Eclipseが停止したと言っています)。

これが解析部分です(私が望むように正確に機能します):

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

int main()
{
    char line[1024] = "[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-3);
    line[len-3] = 0;
    printf("%s \n",line);


    char str[100], *s = str, *t = NULL;

    strcpy(str, line);
    while ((t = strtok(s, " ,")) != NULL) {
        s = NULL;
        printf(":%s:\n", t);
    }
    return 0;
}

可変行のデータは、ファイルの各行を印刷した場合とまったく同じです。しかし、それをコピーしてメインプログラムに貼り付けると、機能しません(QTは何も表示せず、eclipseは最初の行を表示するだけです)。このコードは、上記のコマンドにラップされたほんの数個のファイルIOコマンドです(whileループ内のすべては上記とまったく同じです)

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

int main() {

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

    printf("Starting.. \n");

    int count = 0;
    int list[30]; //items will be stored here

    while(fgets(line, 1024, fp) != NULL){
        count++;
        //char line[1024] = "[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);

        char *s = str, *t = NULL;

        strcpy(str, line);
        while ((t = strtok(s, " ,")) != NULL) {
            s = NULL;
            printf(":%s:\n", t);
        }
    }
    printf(" num of lines is %i \n", count);
    return 0;
}

Eclipse出力:

Starting.. 
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 

何が間違っているのか理解できません。それが助けになるなら、私はgcc4.2を搭載したMacを使用しています。私が考えることができる唯一のことは、リスト変数を解析する方法が間違っているため、後でアクセスできないことです(それが大げさな推測かどうかはわかりません)。足りないものはありますか?

編集:このコードブロックをコメントアウトすると、ファイルを通過します(ただし、解析されません):

while ((t = strtok(s, " ,")) != NULL) {
    s = NULL;
    printf(":%s:\n", t);
}

ファイルの内容は基本的に次のとおりです。

[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],
[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, 1, 2, 2, 2, 4],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 2, 4],

など(その20 + GB)。

EDIT2:Macであるかどうかをテストしたかったのですが、centos 5で試してみました(テストのためにインストールしました)。コマンドラインから実行すると、最後に表示された以外は同じエラーが発生しましたSegmentation fault。上記のサンプル出力をファイルにコピーし、上記のコードのパスを変更して実行しただけです。

4

2 に答える 2

4

lineここには2つの宣言があります。1つはの直後main()、もう1つはの直後whileです。 最初の変数fgetsを読み込みます。linewhileブロック内で、2番目のline宣言は最初の宣言をマスクします(2番目の宣言はよりローカルであるため)。外部line変数(fgets読み込む変数)は、プログラムの他の場所にはアクセスされません。

于 2012-05-31T22:10:09.410 に答える
3

わかった!他のインクルードと一緒に挿入#include <string.h>してみてください。なぜそれを含めずに関数を使用していたのかわかりませんが、<string.h>誤ったリンクが発生しました。コンパイラは次の警告を発行しました。

test2.c:17: warning: incompatible implicit declaration of built-in function ‘strlen’
test2.c:18: warning: incompatible implicit declaration of built-in function ‘memmove’
test2.c:24: warning: incompatible implicit declaration of built-in function ‘strcpy’
test2.c:25: warning: assignment makes pointer from integer without a cast

最初の3つの警告は、ヘッダーファイルがインクルードされていないことを示しています。最後の1つは、宣言がない場合、関数は整数を受け取り、返すと想定されていることを示しています(これは、古代のCコードとの下位互換性のためです)。

fgets行末に改行文字が含まれていることを忘れないでください。len-3に変更して、それを説明する必要がありますlen-4

fcloseまた、使い終わったらファイルを忘れないでください。

また、2番目の文字を指すだけなので、メモは不要です。

char *moved_line = line + 1;
于 2012-05-31T22:37:55.417 に答える