Мне нужно отсканировать значения из .txt в структуру, чтобы я мог дальше работать с моей программой. Я пробовал различные методы из потока, и это закрывает успешную сборку.
Я НЕ могу распечатать значения, поэтому я могу проверить, правильно ли они отсканированы, прежде чем продолжить работу в программе.
У меня разные значения в структуре:
struct knyga
{
char vardas[10];
char pavadinimas[50];
int metai;
double kaina;
};
И это моя функция чтения:
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius;
int txt;
txt = fgetc(fp);
while((txt = fgetc(fp)) != EOF){
if (txt == '\n') skaicius++;
txt = fgetc(fp);
}
printf("%d", skaicius);
fp = fopen("duomenys.txt", "r");
for(int i = 0; i < skaicius; i++){
fscanf(fp, "%s %s %d %lf", arr_knyga[i].vardas, arr_knyga[i].pavadinimas, &arr_knyga[i].metai, &arr_knyga[i].kaina);
}
fclose(fp);
}
Обновлено:
Это содержимое моего текстового файла:
Onute Knyga 1999 12.12
Petras Knygute 2001 9.99
Обновлено еще раз:
Моя основная функция:
int main() {
struct knyga arr_knyga[10];
Skaitymas(arr_knyga);
return 0;
}
Используйте int txt; while((txt = fgetc(fp)) != EOF) { if (txt == '\n') skaicius++; } Большинство функций библиотеки C используют int, а не char для символа.
@WeatherVane спасибо за подсказку, но после того, как я попытаюсь напечатать «skaicius», который должен быть равен 2, потому что это количество строк, которые у меня есть в моем текстовом файле, вместо этого он дает 1.
Если вы хотите проанализировать значения из fp, вы должны использовать fscanf вместо scanf. Проверьте код возврата fscanf (см. документацию) и используйте feof и ferror впоследствии, чтобы узнать, достигнут ли конец файла или произошла ошибка. Вам не нужно сначала считать строки.
Пожалуйста, покажите содержимое входного файла в вашем вопросе. Если вы изменили свою программу, как было предложено в комментарии, пожалуйста, отредактируйте свой вопрос и добавьте измененный код и соответствующий вывод.
Добавлено содержимое файла .txt и отредактирована функция void по рекомендации. @Бодо
Последняя строка входного файла заканчивается на '\n'? Пожалуйста, покажите вывод od -c duomenys.txt
Покажите, как вы вызываете Skaitymas и как определяется массив. Функция Skaitymas не знает размер массива и не может проверить возможный доступ за его пределы.
@Bodo Входной файл точно такой, как я его вставил. Добавил и мою основную функцию. Я предполагаю, что struct knyga arr_knyga[10]; будет иметь максимум 11 строк.
@Upsice Проблема в том, что «точно так, как вы ее вставили» не говорит, заканчивается ли последняя строка символом новой строки или нет. Вот почему я предложил команду, которая прояснила бы это. Если вы объявляете массив как arr_knyga[10], ваша функция Skaitymas не должна пытаться сохранить более 10 записей данных.
Ты слишком часто звонишь txt = fgetc(fp);. Два вхождения этой строки должны быть удалены.
Особенно в цикле у вас есть один вызов fgetc, который проверяется на '\n', и второй вызов, который не проверяется, поэтому существует вероятность 50%/50%, что '\n' не будет засчитан.
Вы забыли инициализировать переменную счетчика.
С этой версией подсчет будет правильным:
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius = 0;
int txt;
while((txt = fgetc(fp)) != EOF){
if (txt == '\n') skaicius++;
}
printf("%d", skaicius);
fclose(fp);
}
Но было бы лучше опустить подсчет строк и определить условие конца файла в цикле fscanf.
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius = 0;
int rc;
while(1)
{
rc = fscanf(fp, "%s %s %d %lf", arr_knyga[skaicius].vardas, arr_knyga[skaicius].pavadinimas, &arr_knyga[skaicius].metai, &arr_knyga[skaicius].kaina);
if (rc == 4)
{
skaicius++;
}
else
{
break;
}
}
if (!feof(fp))
{
fprintf(stderr, "error reading file or wrong data after line %d\n", skaicius);
}
else
{
printf("%d", skaicius);
}
fclose(fp);
}