Как записать CSV-поля в двоичный файл? - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть следующий код:

typedef struct RegDados{

    char removido; //  deve ser inicializado com '-'
    int encadeamento; // deve ser inicializado com -1
    int nroInscricao; // nao aceita valores repetidos nem nulos
    double nota;
    char data[10]; // checar tipo
    char *cidade;
    int sizecid;
    char tagCampo4;
    char *nomeEscola;
    int sizesch;
    char tagCampo5;
}RegDados;

char * strtokEvenEmpty(char * s, const char * seps){

  static char * p = NULL;

  if (s != NULL)
    p = s;
  else if (p == NULL)
    return NULL;
  else
    s = p;

  while (*p) {
    if (strchr(seps, *p)) {
      *p++ = 0;
      return s;
    }
    p += 1;
  }
  return (*s) ? s : NULL;
}

const char * getfield(char* line, int num){

  const char * tok;

  for (tok = strtokEvenEmpty(line, ","); tok; tok = strtokEvenEmpty(NULL, ",\n")){
    if (!--num)
      return tok;
  }
  return NULL;
}

int main(){

  FILE * stream = fopen("trabalho1.csv.csv", "r+");
  FILE * ArqBin = fopen("test.bin","wb");
  RegDados regdados[5000];
  RegCab regcab;
  int i = 0;

  if(ArqBin == NULL) printf("Error");

  if (stream != NULL) {
    char line[1024];
    while (fgets(line, 1024, stream)) {  

      regdados[i].nroInscricao = atoi(getfield(line, 1));
      fwrite(&regdados[i].nroInscricao, sizeof(int), 1, ArqBin);

      regdados[i].nota =  atof(getfield(line, 2));
      fwrite(&regdados[i].nota, sizeof(double), 1, ArqBin); 

      strcpy(regdados[i].data, getfield(line, 3));                             
      fwrite(regdados[i].data, sizeof(char), 100, ArqBin);  

      regdados[i].cidade = getfield(line, 4);
      fwrite(regdados[i].cidade, sizeof(char), 100, ArqBin);

      regdados[i].nomeEscola = getfield(line, 5);
      fwrite(regdados[i].nomeEscola, sizeof(char), 100, ArqBin);  

      i++;
    }
    fclose(stream);
    fclose(ArqBin);
  }
  else{
    printf("Error");
  }
}

Он уже анализирует поля моего файла, но я не могу записать их в двоичный файл, потому что, когда я пытаюсь писать, я получаю много пустых полей, чего не происходит, когда я не пишу .

Мой CSV-файл выглядит так:

nroInscricao, Нота, данные, Cidade, nomeEscola

13893,353.9,26 / 11/2016, FRANCISCO RIBEIRO CARRIL

13595,472.2, Salgueiro, АЛЬФРЕДО РУКОВОДСТВО

13894 614,4,28 / 11/2016, Ресифи, JOAO DE MOURA GUIMARAES

13880,403.2,29 / 11/2016, Форталеза, АНТОНИО ДИАС ПАШОАЛЬ PR

13881 373,7, Сан-Хосе да Тапера, Доницетти Таварес Лим, 1019 *

13882 394,8,01 / 12/2016, Сан-Бернардо-до-Кам, ХУСТИНО ГОМЕС ДЕ КАСТРО

Как записать каждое поле в двоичный файл?

1 Ответ

2 голосов
/ 16 апреля 2019

, когда я пытаюсь написать, я получаю много пустых полей, чего не происходит, когда я не пишу.

это нормально, внутреннее представление числаМожет содержать несколько 0, например:

fwrite(&regdados[i].nroInscricao, sizeof(int), 1, ArqBin);

если regdados[i].nroInscricao значения 7 и ваши int находятся на 32 битах, которые будут записывать 3 раза 0 и 1время 7 (порядок зависит, если вы используете младший / старший порядковый номер).

Конечно, то же самое относится и к строкам, которые вы пишете с фиксированным размером, поэтому символы заполнения могут иметь любое значение, включая 0 (тамне инициализируются)


Ваш способ извлечения полей с помощью getfield стоит дорого, потому что вы извлекаете первый токен, затем, чтобы получить второй, вы должны обойти первый токен, затемчтобы получить третий, вы должны обойти 2 первых токена и т. д.

Лучше всего сделать getfield(line, 1), затем getfield(NULL, 1), чтобы получить второй токен, затем сделать getfield(NULL, 1), чтобы получить третий и т.д.так что на самом деле второй аргумент всегда равен 1, и вы можете удалитье управление


Вы пытаетесь открыть trabalho1.csv.csv, возможно, вы хотите открыть trabalho1.csv


В

if(ArqBin == NULL) printf("Error");

if (stream != NULL) {

недостаточно напечатать ошибку, вы не должны продолжать, может быть

if(ArqBin == NULL) 
  printf("Error");
else if (stream != NULL) {

или лучше заменить

FILE * stream = fopen("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
...
if(ArqBin == NULL) printf("Error");

if (stream != NULL) {
  ...
}
else{
  printf("Error");
}

чем-то вроде

FILE * stream = fopen("trabalho1.csv.csv", "r+");

if (stream == NULL) {
  fprintf(stderr, "cannot open input file rabalho1.csv.csv");
  return -1;
}

FILE * ArqBin = fopen("test.bin","wb");

if (ArqBin == NULL) {
  fprintf(stderr, "cannot open output file test.bin");
  fclose(stream); /* really useful if you do not stop execution */
  return -1;
}
...
...