Как сохранить цикл while в функции при чтении данных с несколькими условиями?

#c #while-loop #conditional-statements

#c #цикл while #условные операторы

Вопрос:

Этот код дает мне исключительные данные, потому что я использовал !pinFound . Поэтому я хочу, чтобы детали были в состоянии. Это означает, pinFound что если я хочу получить результат, то он должен дать мне pinFound только результат или, если я хочу !pinFound результат, тогда он должен дать мне только !pinFound результат.

Я не хочу, чтобы оба результата печатались одновременно , плюс у меня есть несколько функций для чтения данных. Поэтому я не хочу повторять while(fgets(…)) в основной функции снова и снова.

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STRING_LEN 200

int i;
char line[STRING_LEN], *lineOne = NULL, *numbers[5], pinFind[STRING_LEN], *pinFound = NULL;  
int find(FILE * fname, char *findPin){
    while(fgets(line, STRING_LEN, fname)){  
        lineOne = strtok(line, "n");
        numbers[0] = strtok(lineOne, ",");
        for(i = 1; i < 5; i  )
            numbers[i] = strtok(NULL, ",");
        pinFound = strstr(numbers[2], findPin);
        if(!pinFound)
            return line;    
    }
}

int main(){
    FILE * fp1 = fopen("file.csv", "r");
    printf("Enter the pin code: ");
    scanf("%s", pinFind);

    find(fp1, pinFind);
    for(i=0; i<5; i  )
        printf("%sn", numbers[i]);

    return 0;
}
  

Комментарии:

1. «Этот код дает мне исключительные данные, потому что я использовал !pinFound » — это довольно неясно. Какие исключительные данные? Почему вы использовали !pinFound ? Какой результат вы ожидали, для какого точного ввода?

2. Кстати, делать все эти переменные глобальными — плохая идея, но создание i глобальной переменной особенно опасно.

3. @Groo исключительные данные означают, что данные, в которых введен pin-код, не найдены.

4. @Groo Я так долго работал над решением этой проблемы, и я новичок в C

5. Кроме того, return line (где line строка) в функции, объявленной для возврата int ? Что на самом деле должна возвращать функция? И что main функция будет делать с возвращаемым значением?

Ответ №1:

Если я правильно понял ваш вопрос, вы хотели бы извлечь логику итерации файла из остальной части обработки.

Базовое изменение, которое позволило бы вам получить это, было бы просто:

 #include <stdbool.h>

// parse next line, return true if line was parsed
bool nextLine(FILE * fname, char *findPin)
{
    if (fgets(line, STRING_LEN, fname))
    {
        lineOne = strtok(line, "n");
        numbers[0] = strtok(lineOne, ",");
        for (int i = 1; i < 5; i  )
            numbers[i] = strtok(NULL, ",");
        pinFound = strstr(numbers[2], findPin);
        return true;
    }
    else
    {
        return false;
    }
}
  

А затем в main:

 FILE * fp1 = fopen("file.csv", "r");

printf("Enter the pin code: ");
scanf("%s", pinFind);

while (nextLine(fp1, pinFind))
{
    // if you are here, line was parsed, so
    // check the value of 'pinFound'

    if (pinFound)
        doSomething(numbers);
    else
        doSomethingElse(numbers);
}

fclose(fp1);
  

Для домашнего проекта это должно более или менее сработать, но я бы рекомендовал инкапсулировать состояние между nextLine вызовами в отдельную структуру, вместо того, чтобы сохранять его глобальным. Делать все эти переменные глобальными — плохая идея, но создание i глобальной переменной — особенно опасная плохая идея.

Комментарии:

1. Спасибо! другой вопрос в том, почему i это опасно?

2. Если вы постоянно меняете глобальное состояние по всему коду, каждый, казалось бы, простой вызов функции, например, потенциально может изменить результат любого последующего вызова функции. Это очень затрудняет обеспечение корректности программы после ее небольшого увеличения, поскольку результат функции не будет определяться исключительно ее параметрами (чистая функция). Если i является глобальным, то, казалось бы, невинный код, например for (i = 0; i < 5; i ) { doSomething(); } , позволяет doSomething функции меняться i внутри цикла и прерывать работу. Если вы просто используете scope it ( for (int i = 0; ...) ) , вы избавляете себя от проблем.