#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; ...)
) , вы избавляете себя от проблем.