2015-10-11 1 views
-5

Я хочу проверить, имеются ли мои предопределенные данные в файле .dat, который у меня есть. Если это так, я печатаю их. Если нет, моя программа выйдет из строя, потому что функция, которую я написал, не имеет ничего, чтобы вернуться.Программа вылетает, когда функция возвращает пусто

Как исправить это? Как я могу проверить, нет ли совпадения и сказать «Нет совпадения» и предотвратить сбой моей программы?

struct objectList предназначен для моих предопределенных данных. struct database - для данных в .dat-файле.

struct objectList 
{ 
    double oArea; 
    double oLength; 
    double oFormFactor; 
}; 

struct database 
{ 
    char name[15]; 
    double dArea; 
    double dLength; 
    double dFormFactor; 
}; 

Эта функция читает файл и возвращает значение, если только «область», «длина» и «формфактор» матчи.

struct database myReadFile(FILE *rPtr, double area, double length, double formFactor) 
{ 
    struct database fromDb = { "", 0.0, 0.0, 0.0 }; 

    if ((rPtr = fopen("objects.dat", "r")) == NULL) 
     printf("Couldn't open the file to read.\n"); 
    else 
    { 
     fscanf(rPtr, "%s%lf%lf%lf", fromDb.name, &fromDb.dArea, &fromDb.dLength, &fromDb.dFormFactor); 

     while (!feof(rPtr)) 
     { 
      if (fromDb.dArea == area) 
       if (fromDb.dLength == length) 
        if (fromDb.dFormFactor == formFactor) 
        { 
         printf("We have found the %s\n", fromDb.name); 
         return fromDb; 
        } 

      fscanf(rPtr, "%s%lf%lf%lf", fromDb.name, &fromDb.dArea, &fromDb.dLength, &fromDb.dFormFactor); 
     } 
    } 
    fclose(rPtr); 
} 

Эта функция печатает значения.

void getValues(FILE *gPtr, double area, double length, double formFactor) 
{ 
    struct database objectValues = { "", 0.0, 0.0, 0.0 }; 

    objectValues = myReadFile(gPtr, area, length, formFactor); 

    printf("Object name: %s\n", objectValues.name); 
    printf("Object area: %.2lf\n", objectValues.dArea); 
    printf("Object length: %.2lf\n", objectValues.dLength); 
    printf("Object formFactor: %.2lf\n", objectValues.dFormFactor); 
} 

главная:

int main() 
{ 
    struct objectList myObjectList[4]; 
    myObjectList[0] = { 9214.00, 417.24, 22.08 };  // Coin 
    myObjectList[1] = { 54375.00, 1087.94, 49.97 };  // mp3 
    myObjectList[2] = { 12785.00, 550.70, 23.22 };  // toy 
    myObjectList[3] = { 100.01, 200.02, 300.03 };  // Random stuff 

    FILE *cfPtr; 

    if ((cfPtr = fopen("objects.dat", "a +")) == NULL) 
     printf("Couldn't open the file\n"); 
    else 
     fclose(cfPtr); 

    int i = 2; 
    getValues(cfPtr, myObjectList[i].oArea, myObjectList[i].oLength, myObjectList[i].oFormFactor); 
    return 0; 
} 

Мой файл .dat имеет "игрушку", "монета", "mp3", но не "случайные вещи". Поэтому, когда i = 3, моя программа вылетает из строя.

+0

@massakrienen Не все пути 'myReadFile' возвращают значение. – LogicStuff

+1

Включите предупреждения компилятора и сделайте их ошибки! Если вы не получите жалобу, используйте лучший компилятор. – Olaf

+0

Как вы уже знаете, вы не возвращаете действительное значение, почему вы должны спрашивать здесь? – Olaf

ответ

1

Основная проблема, которую я вижу с вашим кодом является цикл чтения, он имеет в основном два вопроса

  1. чтения: Why is while (!feof(rPtr)) always wrong.

  2. Вы должны проверить возвращаемое значение scanf() и предотвратить scanf() «S от переполнения буфера назначения, так что условие цикла должно быть

    while (fscanf(rPtr, "%14s%lf%lf%lf", fromDb.name, &fromDb.dArea, 
          &fromDb.dLength, &fromDb.dFormFactor) == 4) 
    

Как об этом

int 
myReadFile(struct database *db, double area, double length, double formFactor) 
{ 
    FILE *rPtr; 
    if ((rPtr = fopen("objects.dat", "r")) == NULL) 
     printf("Couldn't open the file to read.\n"); 
    else 
    { 
     while (fscanf(rPtr, "%14s%lf%lf%lf", db->name, &db->dArea, 
      &db->dLength, &db->dFormFactor) == 4) 
     { 
      if ((db->dArea != area) || (db->dLength != length) || 
       (db->dFormFactor != formFactor)) 
      { 
       continue; 
      } 
      fclose(rPtr); 
      return 0; 
     } 
    } 
    fclose(rPtr); 
    return -1; 
} 

И в основной функции

struct database result; 
if (getValues(&result, myObjectList[i].oArea, 
    myObjectList[i].oLength, myObjectList[i].oFormFactor) == 0) 
{ 
    fprintf(stderr, "%s\n", result.name); 
} 
+0

Спасибо. Очень гладкая и то, что я хотел. Должен ли я также закрывать файл, когда функция возвращает 0? – massakrienen

+0

Да, вы должны !!! Я пропустил это, я добавлю его к ответу за полноту. О, также вам не нужно передавать 'rPtr' функции, возможно, вместо этого перейти к файлу, что сделает функцию более многоразовой –