0

(「|」で区切られた)ファイルから入力を受け取る小さなプログラムを作成しようとしています。たとえば、ファイルの1行は次のようになります。

name|phone|address|city|state|zip

何らかの理由で、構造体の配列にあるすべてのものをバイナリファイルに書き込もうとするたびに、配列のリンクが失敗します。私はこれを数時間見てきましたが、なぜこれが行われるのか理解できません。私が気付いた問題の1つは、プログラムを実行することにし、インデックス1に何かを書き込んだ後、配列のインデックス0にあるものを出力すると、インデックス0が台無しになることです(各インデックスは構造体を保持します)。理由はわかりません。

助けてください、私は何時間もキーボードに頭をぶつけて、なぜそれが私にこの問題を引き起こすのかを理解しようとしています。申し訳ありませんが、最初のパラメータをファイルへのパスとして実行する必要があることを忘れてしまいました。例:./ExerciseOne.out /path/to/file.txt

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


/*
 * ExerciseOne.c
 *
 *  Created on: Sep 24, 2012
 *      Author: kevin
 */

typedef struct personal_Info {
    char *Name;
    char *Phone;
    char *address;
    char *city;
    char *state;
    int zip;

} PInfo ;

void loopTokens(PInfo *, char *);
void PrintStruct(PInfo *);
void PrintStructArray(PInfo p[], int);
void transferText(PInfo *, int);
void transferTextBin(PInfo p[], int);
void readTextBin(FILE *, PInfo *, int );

int main(int argc, char *argv[]){
    int index = 0;
    int numLines = 0;
    char *lineOfText = malloc(80);
    //Open File
    FILE *fp;
    if ((fp = fopen(argv[1], "r")) == NULL){
    printf("File could not be opened");
    }
    else {
        fclose(fp);
    fp = fopen(argv[1], "r");//inputs the argv as the vile to read
    }
    fscanf(fp, "%d \n", &numLines);


    //Create Arrays for Binary and Text structs
    PInfo TextInfo[numLines];
    PInfo *TextInfo_ptr;



/*Commented code
 * TextInfo[index] = *TextInfo_ptr;//Point to structure ##Unneeded##
 *  printf("this is before the transferTextBin %s \n", TextInfo[0].Phone);//Works
 */
    while(!feof(fp)&&index<numLines){
      TextInfo_ptr = &TextInfo[index];//Structure points to the proper hole in array; current index//Looks like it advances the count for the ptr
      fgets(lineOfText, 80, fp);
      loopTokens(TextInfo_ptr,  lineOfText);//puts pointer to the array index into function
      printf("this is before the transferTextBin %s \n", TextInfo_ptr->Phone);//Works
      printf("this is before the transferTextBin %s \n", TextInfo[0].Phone);//problem second time around
      printf("this is before the transferTextBin %s \n", TextInfo[1].Phone);//works
      //PrintStruct(TextInfo_ptr);
      index++;
    }


    //transferText(TextInfo, numLines);//Will do it in regular

    printf("this is before the transferTextBin %s \n", TextInfo[0].Phone);//Here it is suddenly losing it
    transferTextBin(TextInfo, numLines);//will do it in bin

    fclose(fp);
    FILE *fBIN;
    fBIN = fopen("fOUT.dat", "rb");// may need to insert this into method
    //readTextBin(fBIN, BinInfo, numLines);
    return(0);
}


void loopTokens(PInfo *p, char *textLine){//Want to pass in INDIVDUAL structs
    char *buffer;
    int index = 0;

  p->Name = malloc(80);
  p->Phone = malloc(80);
  p->address = malloc(80);
  p->city = malloc(80);
  p->state = malloc(80);
  p->zip = 0;

        /* mallocate each field in the current structure */

    buffer = strtok(textLine, "|"); /* Tokenize the string */

    while(buffer != NULL && strcmp(textLine,"\n")){ /* loop through all tokens */
            if(index == 0){
            //strcpy(p->Name,textLine);
            p->Name = buffer;
            buffer = strtok(NULL, "|");
            index++;
            }
            else if(index == 1){
            p->Phone = buffer;
            buffer = strtok(NULL, "|");
            index++;
            }
            else if(index == 2){
            p->address = buffer;
            buffer = strtok(NULL, "|");
            index++;
            }
            else if(index == 3){
            p->city = buffer;
            buffer = strtok(NULL, "|");
            index++;
            }
            else if(index == 4){
            p->state = buffer;
            buffer = strtok(NULL, "|");
            index++;
            }
            else if(index == 5){
                p->zip = 0;
            p->zip = (int)atoi(buffer);
            buffer = strtok(NULL, "|");
            index++;
            }
  }
  index = 0;

}

    void PrintStruct(PInfo *p){//Gets pointer to the struct
        printf("This is the supposed name: %s The Phone is : %s, the address is : %s %s %s %d\n", p->Name, p->Phone, p->address, p->city, p->state, p->zip );
    }
    void PrintStructArray(PInfo p[], int lines){//Gets Entire array of structs; prints everything out
  int index = 0;
    while(index < lines){
      printf("This is the supposed name: %s The Phone is : %s, the address is : %s %s %s %d\n", p[index].Name, p[index].Phone, p[index].address, p[index].city, p[index].state, p[index].zip );
    }
  }
void transferText(PInfo *p, int numLines){//Transfers text
  FILE *fOUT;//open file for writing
  int index = 0;
        fOUT = fopen("fOUT.txt", "w");//Open file for writing

        while(index < numLines){
          fputs(p->Name,fOUT);
          fputs(p->Phone,fOUT);
          fputs(p->address,fOUT);
          fputs(p->city,fOUT);
          fputs(p->state,fOUT);
          fputs(p->zip,fOUT);
        }

        fclose(fOUT);

    }
void transferTextBin(PInfo p[], int numLines){
    FILE *fOUT;//open file for writing
    //int index = 0;
    fOUT = fopen("fOUT.dat", "wb");
    printf("this is the phone of the first index %s", p[0].Phone );
    //printf("Ti the supposed name: %s The Phone is : %s, the address is : %s %s %s %d\n", p[index].Name, p[index].Phone, p[index].address, p[index].city, p[index].state, p[index].zip );
    //while(index < numLines){
/*  fwrite(p[index]->Name, sizeof(p[index]->Name), 1, fOUT);
    fwrite(p[index]->Phone, sizeof(p[index]->Phone), 1, fOUT);
    fwrite(p[index]->address, sizeof(p[index]->address), 1, fOUT);
    fwrite(p[index]->city, sizeof(p[index]->city), 1, fOUT);
    fwrite(p[index]->state, sizeof(p[index]->state), 1, fOUT);*/
    //fwrite(p->zip, sizeof(p->zip), 1, fOUT);
//  }
    fclose(fOUT);
    }







void readTextBin(FILE *fIN, PInfo *bInfo, int numLines){
    int index = 0;
    //char *buffer;
    printf("This is what is in the File: ");
    //bInfo[index].Name = fread(buffer, 80, 1, fIN);
    //bInfo[0]->Name = malloc(80);
    while(!feof(fIN) && index<numLines){
        fread(bInfo[index].Name, 80, 1, fIN);
        fread(bInfo[index].Phone, 80, 1, fIN);
        fread(bInfo[index].address, 80, 1, fIN);
        fread(bInfo[index].city, 80, 1, fIN);
        fread(bInfo[index].state, 80, 1, fIN);
        //fread(bInfo[index]->zip, 80, 1, fIN);
        PrintStruct(bInfo);
        index++;
    }
}
4

2 に答える 2

1

では、バッファからメンバーへの値loopTokensを取得する必要があります。名前、住所などの記憶、strcpytextLinechar*malloc

void loopTokens(PInfo *p, char *textLine){
    char *buffer;
    int index = 0;

    p->Name = malloc(80);
    /* snip */
    buffer = strtok(textLine, "|"); /* Tokenize the string */

    while(buffer != NULL && strcmp(textLine,"\n")){ /* loop through all tokens */
            if(index == 0){
            //strcpy(p->Name,textLine);
            p->Name = buffer;
            buffer = strtok(NULL, "|");
            index++;
            }

しかし、eg を割り当てると、ed メモリp->Name = buffer;への参照が失われmalloc(悪い)、 let がp->Name指すchar配列内の a を指しtextLineます。strtok呼び出されたバッファーを変更し、NULLそのバッファーへのポインターを返します (または)。

そのp->Nameため、友人はすべてtextLineバッファーを指し、次の行を読むとその内容が変化します。

の代わりにp->Name = buffer;

strcpy(p->Name, buffer);

p->Name( によりも少ないメモリを割り当てているため、 が返されたtextLineかどうかを確認すれば、割り当てられたメモリの外側に書き込む危険はありません)。mallocNULL

于 2012-10-07T10:47:55.580 に答える
1
void loopTokens(PInfo *p, char *textLine){
    char *tok;
    int index = 0;

    if(!strcmp(textLine,"\n")) return; /* loop-invariant moved out of the loop */

    for(tok= strtok(textLine, "|"); tok; tok = strtok(NULL, "|") ) {
        switch(index++) {
          case 0:
          p->Name = strdup(tok);
            break;
        case 1:
            p->Phone = strdup(tok);
            break;
        case 2:
            p->address = strdup(tok);
            break;
        case 3:
            p->city = strdup(tok);
            break;
        case 4:
            p->state = strdup(tok);
            break;
        case 5:
            p->zip = 0;
            p->zip = atoi(tok);
            break;
        default:
            return;
            }
     }

}
于 2012-10-07T11:03:40.763 に答える