簡體   English   中英

使用fgets()從文件讀取然后使用另一個函數中的信息

[英]reading from file using fgets() then using information in another function

我有這樣的文本文件:

123-55555-1 10000 0   
123-55533-3 12300 500 
123-99971-3 50000 0 
123-38951-2 350 10  
120-39888-0 4910 100   
121-12345-3 50000 150 
121-xptoz-3 1000 100  
150-23857-1 350000 20000 
521-71750-4 500000 25000 
191-11999-7 1200

我想要的是能夠使用fgets()逐行檢索此信息。 當我讀它時,我想調用另一個使用行讀取的函數來處理信息並將其放在列表中。 問題是,當我嘗試調用函數並將字符串作為參數傳遞時,它給出了seg錯誤:11。 這是我的代碼。

typedef struct identificador_s
{
  int a;
  int b;
  int c;

} identificador;

typedef struct contaBancaria_s
{
  identificador id;
  int saldo;
  unsigned short int credito;
  struct contaBancaria_s * proximo;

} contaBancaria;

contaBancaria * contaP = NULL;
char contas[] = "contas.txt";
char movimentos[] = "movimentos.txt";

char divideString(char line[], int contagem, char parametro[])
{
  int i = 0;
  char *a = NULL;
  char string1;
  a = strtok(line, parametro);
  while (i != contagem)
  {
    a = strtok(NULL, parametro);
    i++;
  }
  string1 = (char) *a;
  return string1;

}

void contaFill(char line[])
{
  printf("passo -2");
  contaBancaria * p = malloc(sizeof(contaBancaria));
  printf("passo 0");
  int i = 0;
  char parametro1[] = "-";
  char parametro2[] = " ";
  p->id.a = (int) divideString(line, i, parametro1);
  printf("passo 1");
  p->id.b = (int) divideString(line, i += 1, parametro1);
  printf("passo2");
  p->id.c = (int) divideString(line, i += 1, parametro1);
  printf("passo 3");
  /*if(!(validaIdentificador(p-id.a,p->id.b,p-id.c))){
   return;
   }*/
  p->saldo = (int) divideString(line, i += 1, parametro2);
  printf("passo 4");
  p->credito = (int) divideString(line, i += 1, parametro2);
  printf("passo 5");
  printf("%d - %d - %d %d %d", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
}

void loadFile(char fileType[])
{
  FILE * fp;
  fp = fopen(fileType, "r");
  int size = 100;
  char buffer[100];
  char string1[100];
  if (fp)
  {
    while (fgets(buffer, 100, fp) != NULL)
    {
      puts(buffer);
      if (strcmp(fileType, "contas.txt") == 0)
      {
        contaFill(buffer);
      }
    }
    fclose(fp);
  }
}

int main(int argc, char* argv[])
{
  loadFile(contas);
  return 0;
}

你的代碼崩潰在這里:

string1 = (char) *a;

你會在任何調試器中看到這一點。 首先,請注意這里的(char)是不必要的。 但真正的問題是a有時是NULL ,因此無法解除引用。 在這種情況下,您需要弄清楚您想要做什么。

首先調用divideString(line, i, parametro1);

p->id.a = (int) divideString(line, i, parametro1);

返回值為'1' - > 49

第一個'-' line替換'\\0'strtok

(例如"123-55555-1 10000 0" - > "123\\055555-1 10000 0"意思是“123”

第二次調用divideString(line, i += 1, parametro1);

a = strtok(line, parametro);//not find parametro return `a=line`(top)
...
a = strtok(NULL, parametro);//a=`NULL`
...
string1 = (char) *a;//*(NULL) seg fault!!

更新

設置在一起並停止調用( divideString )每個成員。

例如

void stringToContaBancaria(char line[], contaBancaria *p, char para1[], char para2[]){
    char *a, *endp;
    //To convert to int from numeric strings for example it use strtol
    p->id.a    = strtol(a=strtok(line, para1), &endp, 10);
    if(*endp) fprintf(stderr, "id.a not number : %s\n", a);
    p->id.b    = strtol(a=strtok(NULL, para1), &endp, 10);
    if(*endp) fprintf(stderr, "id.b not number : %s\n", a);
    p->id.c    = strtol(a=strtok(NULL, para2), &endp, 10);
    if(*endp) fprintf(stderr, "id.c not number : %s\n", a);
    p->saldo   = strtol(a=strtok(NULL, para2), &endp, 10);
    if(*endp) fprintf(stderr, "saldo not number : %s\n", a);
    p->credito = strtoul(a=strtok(NULL, para2), &endp, 10);
    if(*endp) fprintf(stderr, "credito not number : %s\n", a);
}

void contaFill(char line[]){
    contaBancaria * p = malloc(sizeof(contaBancaria));
    char parametro1[] = "-";
    char parametro2[] = " ";//" \n"?
    stringToContaBancaria(line, p, parametro1, parametro2);
    printf("%d - %d - %d %d %hu\n", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
    //free(p);//deallocate! 
}

它給了我seg錯誤

    //less a(=strtok return value) becomes to NULL element when reading is less than expected.
    p->credito = strtoul(a=strtok(NULL, para2), &endp, 10);
    if(*endp) fprintf(stderr, "credito not number : %s\n", a);

例如改為

    if(NULL!=(a=strtok(NULL, para2))){
        p->credito = strtoul(a, &endp, 10);
        if(*endp)fprintf(stderr, "credito not number : %s\n", a);
    } else
        fprintf(stderr, "credito not exist\n");

但我認為檢查之前的時間而不是在閱讀這些必要的項目之間是否存在。


做一個簡單的預檢

#include <ctype.h>

int isInvalidRecord(char line[]){
//[number]-[number]-[number][space][number][space][number][space*]
//521-71750-4 500000 25000[newline]
    int i=0, j;
    while(isdigit(line[i]))++i;
    if(i==0 || line[i]!='-') return 1;//1st item bad
    j=++i;
    while(isdigit(line[i]))++i;
    if(i==j || line[i]!='-') return 2;
    j=++i;
    while(isdigit(line[i]))++i;
    if(i==j || line[i]!=' ') return 3;
    j=++i;
    while(isdigit(line[i]))++i;
    if(i==j || line[i]!=' ') return 4;
    j=++i;
    while(isdigit(line[i]))++i;
    if(i==j || (line[i]!='\0' && !isspace(line[i]))) return 5;
    return 0;//ALL OK
}

void contaFill(char line[]){
    contaBancaria * p = malloc(sizeof(contaBancaria));
    char parametro1[] = "-";
    char parametro2[] = " ";//" \n"?
    int check = isInvalidRecord(line);
    if(check == 0)//0 is OK
        stringToContaBancaria(line, p, parametro1, parametro2);
    else
        fprintf(stderr, "%s %d item(near) is bad\n", line, check);
    printf("%d - %d - %d %d %hu\n", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
    //free(p);//deallocate! 
}

好吧,你的代碼中存在很多問題。我已經嘗試修復所有錯誤並且其工作正常沒有,這是我做的改進:

這里

函數strtok(); 返回指定給a的指針類型,而應將其指定給*a

我在評論(//)中寫了任何其他改進。

#include<stdio.h>
#include<stdlib.h>
typedef struct identificador_s
{
  int a;
  int b;
  int c;

} identificador;

typedef struct contaBancaria_s
{
  identificador id;
  int saldo;
  unsigned short int credito;
  struct contaBancaria_s * proximo;

} contaBancaria;

contaBancaria * contaP = NULL;
char contas[] = "contas.txt";
char movimentos[] = "movimentos.txt";

char divideString(char line[], int contagem, char parametro[])
{
  int i = 0;
  char *a = NULL;
  char string1;
  *a = strtok(line, parametro);
  while (i != contagem)
  {
    *a = strtok(NULL, parametro);
    i++;
  }
  string1 = (char) *a;
  return string1;

}

void contaFill(char line[])
{
  printf("passo -2");
  contaBancaria *p=malloc(sizeof(contaBancaria));
  printf("passo 0");
  int i = 0;
  char parametro1[] = "-";
  char parametro2[] = " ";
  p->id.a = (int) divideString(line, i, parametro1);
  printf("passo 1");
  p->id.b = (int) divideString(line, i += 1, parametro1);
  printf("passo2");
  p->id.c = (int) divideString(line, i += 1, parametro1);
  printf("passo 3");
  /*if(!(validaIdentificador(p-id.a,p->id.b,p-id.c))){
   return;
   }*/
  p->saldo = (int) divideString(line, i += 1, parametro2);
  printf("passo 4");
  p->credito = (int) divideString(line, i += 1, parametro2);
  printf("passo 5");
  printf("%d - %d - %d %d %d", p->id.a, p->id.b, p->id.c, p->saldo, p->credito);
}

void loadFile(char fileType[])
{
  FILE * fp;
  fp = fopen(fileType, "r");
  int size = 100;
  char buffer[100];
  char string1[100];
  if (fp)
  {
    while (fgets(buffer, 100, fp) != NULL)
    {
      puts(buffer);
      if (strcmp(fileType, "contas.txt") == 0)
      {
        contaFill(buffer);
      }
    }
      }
  fclose(fp);// file should close outside the if statement 
}

int main(int argc, char* argv[])
{
  loadFile(contas);
  return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM