2017-12-21 10 views
0

私は学校のプロジェクトで、chars *やその他の変数を使ってリンクリストを使用する必要があります。問題は次のとおりです。main()と関数(リスト)の間で値を渡せません

サブ関数を使用してリスト内のデータを開いて読み込み、格納していますが、文字列にアクセスできません。他の情報が表示されています。 ..

void main() 
{ 
    Palavra* P = lerPalavras(); 
    printf ("%s", P->c);    //Was just testing in this ... 
} 

サブ目的球

Palavra* lerPalavras()    //Just ignore what is going on here in the code, the problem is when I call it, within the function the output works just fine, but when I pass to main it's just not working at all. Thanks 
{ 
    char linha [50]; 
    Palavra* P = NULL; 
    Palavra* pv = NULL; 
    FILE* ficheiro = fopen ("keywords.txt", "r"); 

    if(ficheiro == NULL) 
    { 
     printf ("Abertura do Ficheiro 'keywords.txt' Falhou!"); 
     return NULL; 
    } 
    while (fgets (linha, sizeof (linha), 
    { 
     if (linha [strlen(linha) - 1] != '\n') 
      linha [strlen(linha)] = '\0'; 
     else 
      linha [strlen(linha) - 1] = '\0'; 
     pv = CriaKW(); 
     pv->c = linha; 
     pv->tam = strlen (linha); 
     P = insertKW (P, pv); 
    } 
    fclose (ficheiro); 
    return (P); 
} 

構造体 "Mensagem"

typedef struct KW 
{ 
    char* c; 
    struct KW* nseg; 
    int ID; 
    long int tam; 
} Palavra; 

機能 "CriaKW"

Palavra* CriaKW()           
{ 
    Palavra * pv = (Palavra*) malloc (sizeof (Palavra)); 
    return (pv); 
} 

機能「insertKW」

Palavra* insertKW (Palavra* P, Palavra* pv) 
{ 
    pv->nseg = NULL; 
    if (P == NULL)      //Ver se a Lista está vazia 
     return (pv); 
    Palavra* p = P;      //Variável Auxiliar para não perder a cabeça da Lista 
    while (p->nseg != NULL)    //Ver se a "caixa" tem seguinte 
     p = p->nseg;     //Correr a Lista 
    p->nseg = pv; 
    return (P); 
} 
+0

字下げと書式設定を修正してください。すべてのコード行の前に4つのスペースを入れてください。 –

+0

ありがとうございました@ppz、 –

+0

[分岐とループに常に中括弧を使用する]ことをお勧めします(https://stackoverflow.com/questions/2125066/is-it-bad-practice-to -use-an-if-statement-bracketsなし)。 – Galen

答えて

0

配列linha機能

Palavra* lerPalavras() 
{ 
    char linha [50]; 
    //... 

のローカルオブジェクトであり、自動保管期間を有する、機能を出た後、それは生きていることができませんプログラムの他のオブジェクトによって上書きされたり、アクセスできないことさえあります。

いずれの場合においても、このよう

pv->c = linha; 

を初期化し、各ノードのポインタpv->c機能を終了した後、無効な値を有することになります。

このポインタが指すメモリを動的に割り当てて、元の文字列を割り当てられたメモリにコピーする必要があります。

linha[ strcspn(linha, "\n") ] = '\0'; 
size_t n = strlen(linha); 

pv->c = malloc(n + 1); 
strcpy(pv->c, linha); 
pv->tam = n; 

例えば

また、あなたは、リストのノードが削除されたときに、文字列に割り当てられたメモリを解放するために覚えておく必要があります。

一般的に、タイプsize_tが標準機能strlenと他の文字列かかわらタイプlong intと同等である必要はないので、それがデータメンバーtam用タイプsize_tを使用した方が良い代わりにタイプlong intのあることを考慮してください関数はタイプsize_t.を使用します。

size_t tam; 
0

によるラインには2つの問題があります:pv->c = linha;

  1. 、それが戻っていた構造内のローカル変数へのポインタを保存しています。その変数は、関数が戻るときに破棄されるため、ポインタはもはや有効ではありません。
  2. あなたが読んだ行ごとに同じlinha変数を使用しています。したがって、変数が破棄されない場合でも、すべてのPalavra構造体はファイルの最後の行を持ちます。

保存するには、行のコピーを作成する必要があります。それはあなたのコードの制限だ場合はmalloc()strcpy()を使用して、それを自分で書くことのために、それは簡単であるべきPOSIX機能ではなく、標準のCである。

pv->c = strdup(linha); 

strdup():にその行を変更します。

ところで、この行は必要ありません。\0文字の位置を見つけることによって

 linha [strlen(linha)] = '\0'; 

strlen()以降の作品は、これはちょうどそれがすでに持っているものにその文字を設定しています。これはに含まれif変更:

if (linha[strlen(linha)-1] == '\n') { 
    linha[strlen(linha)-1] = '\0'; 
} 
0

皆様、ありがとうございます。私はここで新しいですが、みなさんが助けようとしました!どうもありがとう!

このコードを作成しましたか? pv-> c = strdup(linha);

+0

実際にはコメントであるため、この回答を削除する方がよいでしょう。さもなければ誰かがそれをダウン投票することができます。 –

関連する問題