Fscanf c ошибка

Hey I’ve tried a lot of programs in Visual Studio and in most of them when i try taking the input from a stream ( while using fscanf ) it invariably throws a debug assertion failed error ..

and goes on to say:

stream != NULL. Since I have gotten this error a number of times .. I assume there is a flaw in the way I’m using fscanf. I would appreciate it if someone could tell me the usage or .. give me a demo sample code that illustrates the simple usage .. !

I tried looking up the error .. in most places it said I haven’t closed the file .. but I have and I’m a little confused .. I appreciate any help .. thanks a lot :)

    printf("Enter No of states\n");
     Q=5;
  //  scanf("%d",&Q);

   // READING ZERO MATRIX
  // reading the matrix from f0.sta
 {
  FILE *fp;
   fp = fopen("c:\\tc\\fuzzy\\f0.sta","r");
   for(i=1;i<=Q;i++)
    for(j=1;j<=Q;j++)
     fscanf(fp,"%f",&a0[i][j]);

    fclose(fp);
 }
 // READING ONE MATRIX
 // reading the matrix from f0.sta
   FILE *fp;
    fp = fopen("c:\\tc\\fuzzy\\f1.sta","r");
     for(i=1;i<=Q;i++)
      for(j=1;j<=Q;j++)
        fscanf(fp,"%f",&a1[i][j]);

    fclose(fp);

This is the code bit.

Mysticial's user avatar

Mysticial

465k45 gold badges335 silver badges332 bronze badges

asked Jan 3, 2012 at 7:52

abhishek b's user avatar

4

It sounds like fp is NULL. The most likely reason is that one of the files (or both) do not exist, or can’t be opened (for example, because some other process is using it).

I would start by adding some error checking after the two fopen() calls: compare the result to NULL and if it is NULL, examine errno.

answered Jan 3, 2012 at 18:51

NPE's user avatar

NPENPE

487k108 gold badges951 silver badges1013 bronze badges

2

Your loop counters start at 1 instead of 0, which is odd for C programming. What’s likely happening is you’re not allocating enough space in the array, i.e. you have

double a[5][5];

when you need

double a[6][6];

so you’re stepping on something past the end of the array. Better to have your loop be

for(i=0;i<Q;i++)
  for(j=0;j<Q;j++)

so you don’t waste the 0 slots in the array.

answered Jan 3, 2012 at 18:55

Kyle Jones's user avatar

Kyle JonesKyle Jones

5,4821 gold badge21 silver badges30 bronze badges

0

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {
    int test, l , b, sqr, area, sqra, num;
    fscanf(stdin, "%d", &test);
    while(test--) {
        fscanf(stdin, "%d %d", &l, &b);    //input:
        area = l * b;                      //2
        sqr = sqrt(area);                  //2 2
        sqra = sqr * sqr;                  //7 9
        while(sqr) {
            if(!(area % sqra)) {
                num = area / sqra;
                --sqr;
                break;
            }
        } 
        fprintf(stdout, "%d\n", num);
    }
    return 0;
}

my code does not works when test >= 2. I think the problem is with fscanf. Can you explain why is that?

asked Jun 3, 2013 at 18:03

donkey's user avatar

donkeydonkey

4631 gold badge4 silver badges14 bronze badges

5

I don’t think it has to do anything with scanf, for example: if l=2 and b=3 then area=6, sqrt(area) is int so it’s being rounded to 2, then sqra=4, area%sqra is then 6%4=2, so it never goes into the condition in the loop which creates an infinite loop.

Same goes to the 2nd input in your example : 7*9=63 => sqr=7 => sqra = 49 => area%sqra=14. Again, infinite loop.

answered Jun 3, 2013 at 18:10

Tomer Arazy's user avatar

Tomer ArazyTomer Arazy

1,83310 silver badges15 bronze badges

2

You should really use scanf, not fscanf for this, and, also, where did you declare num at? I’m surprised it compiles at all. Also, the case where you have area is not divisible by sqra will have an infinite loop. (such as a rectangle with sides 3 and 7)

answered Jun 3, 2013 at 18:06

Triclops200's user avatar

Triclops200Triclops200

8235 silver badges22 bronze badges

1

[after declaring num]
Your fscanf works fine:

    fscanf(stdin, "%d %d", &l, &b);
    printf("inp: %d %d\n",l,b);

Try printing the user input. it works. Your code logic is wrong so that only you are not getting expected result.

answered Jun 3, 2013 at 18:11

Dineshkumar's user avatar

DineshkumarDineshkumar

4,1655 gold badges30 silver badges43 bronze badges

Код считывает массив структур из файла. Но в функции main, почему то выводит мусор. Как это можно исправить? (В файле данные расположены так: «Солнечный,Самара,Москва,пеший,4,29»):

#include <stdio.h>
#include <stdlib.h>
#include <locale>
#include <conio.h>


struct Routes
{
	char title[32];
	char start[32];
	char finish[32];
	char type[32];
	int complexity;
	int duration;
}; // 6 записей

int size = 0;
Routes* arr = (Routes*)malloc(size * sizeof(Routes));

// Загрузить данные из файла
void get_datas(Routes *arr, int* size)
{
	FILE* file;
	file = fopen("datas.txt", "r");
	if (file == NULL) { printf("Ошибка открытия файла"); return; }
	int count = *size;
	int record = *size;
	int read; // Кол-во записей
	do
	{
		count++;
		arr = (Routes*)realloc(arr, count * sizeof(Routes));

		read = fscanf(file, "%32[^,],%32[^,],%32[^,],%32[^,],%d,%d\n",
			arr[record].title,
			arr[record].start,
			arr[record].finish,
			arr[record].type,
			&arr[record].complexity,
			&arr[record].duration
			);

		if (read == 6) record++;
		if (read != 6 && !feof(file)) return; // Неправильный формат файла
		if (ferror(file)) return; // Если произойдет ошибка
	} while (!feof(file));
	fclose(file);
	*size = count;
}

int main()
{
	setlocale(LC_ALL, "ru");
	printf("%d\n", size);
	get_datas(arr, &size);

	printf("%d\n", size);

	for (int i = 0; i < size; i++)
	{
		printf("%s %s %s %s %d %d", arr[i].title,
			arr[i].start,
			arr[i].finish,
			arr[i].type,
			arr[i].complexity,
			arr[i].duration);
	}

	free(arr);
}

У вашего цикла есть несколько проблем. Вы написали:

while( fscanf( f, "%[^\n\r]s", cLine ) != EOF ) 
    /* do something */;

Некоторые моменты, которые следует учитывать:

  1. fscanf () возвращает количество сохраненных элементов. Он может вернуть EOF, если он читает после конца файла или если дескриптор файла содержит ошибку. Вам нужно отличать действительный возврат нуля, когда в буфере cLine нет нового содержимого, от успешного чтения.

  2. У вас действительно есть проблема, когда происходит сбой сопоставления, потому что трудно предсказать, куда теперь указывает дескриптор файла в потоке. Это затрудняет восстановление после неудачного матча, чем можно было бы ожидать.

  3. Написанный вами шаблон, вероятно, не соответствует вашим задумкам. Он сопоставляет любое количество символов, не являющихся CR или LF, а затем ожидает найти литерал s.

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

  5. Если вы специально не запросили, чтобы f был открыт в двоичном режиме, перевод концов строки будет происходить в библиотеке, и вы, как правило, никогда не увидите символы CR, и обычно не в текстовых файлах.

Вероятно, вам нужен цикл, похожий на следующий:

while(fgets(cLine, N_CLINE, f)) {
    /* do something */ ;
}

где N_CLINE — количество байтов, доступных в буфере, начиная с cLine.

Функция fgets() — наиболее предпочтительный способ чтения строки из файла. Его второй параметр — это размер буфера, и он читает из файла в буфер на 1 байт меньше этого размера. Он всегда завершает буфер символом nul, чтобы его можно было безопасно передать другим строковым функциям C.

Он останавливается при чтении первого из конца файла, новой строки или buffer_size-1 байтов.

Он оставляет символ новой строки в буфере, и этот факт позволяет вам отличить одну строку длиннее, чем ваш буфер, от строки, короче, чем буфер.

Он возвращает NULL, если байты не были скопированы из-за конца файла или ошибки, а в противном случае — указатель на буфер. Вы можете использовать feof() и / или ferror(), чтобы различать эти случаи.

person
RBerteig
  
schedule
14.05.2009

Visual C++: почему fscanf не читает числа в цикле

Решал человек в Visual Studio (C++) типовую задачку по форматному чтению данных из текстового файла. Например:

Файл text.txt в текущей папке приложения имеет следующий вид:
1 1.5 -3.5
2 3.5
Прочитать его как последовательность вещественных чисел.

Вот программа:

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
 setlocale(LC_ALL,"Rus"); 
 SetConsoleCP(1251); SetConsoleOutputCP(1251);

 FILE *fp = fopen ("text.txt","r");
 if (fp==NULL) {
  printf ("\nне удалось открыть файл");  getchar(); exit (1); 
 }
 float a;
 while (1) {
  fscanf (fp,"%f",&a);
  if (feof(fp)) break; //Если файл кончился, выйти из цикла 
  //здесь выполняется обработка очередного значения a, например:
  printf ("%.2f ",a);
 }
 fclose(fp);
 
 fflush(stdin); getchar();  return 0;
}

Увы, при её запуске в консоли бесконечно «крутится» только прочитанная первой «единичка», будто и не работает цикл while.

В чём причина? Да она не одна. На самом деле, к такой программке требуется сделать минимум 5 пояснений:

1. Функции семейства scanf возвращают целое число — количество значений, которые успешно прочитаны в соответствии с указанным форматом. В реальных приложениях эту величину следует проверять в коде:

int i=fscanf (fp,"%f",&a);
if (i!=1) {
 //не удалось получить 1 значение
}

2. На «восприятие» программой данных может влиять установленная в приложении локаль. Например, если до показанного кода выполнен оператор

setlocale(LC_ALL,"Rus");

результат работы кода может измениться (для русской локали разделителем целой и дробной части числа является запятая, а не точка).

3. Очередное чтение данных изменяет внутренний файловый указатель. Этот указатель в любой момент времени, пока файл открыт, показывает на следующее значение, которое будет прочитано. Благодаря этому наш код с «бесконечным» while не зациклился.

4. Код показывает, как читать из файла заранее неизвестное количество значений – это позволяет сделать стандартная функция feof (проверка, достигнут ли конец файла; вернёт не 0, если прочитано всё).

5. Распространённый в примерах из Сети код вида

while (!feof(fp)) {
 fscanf (fp,"%f",&a);
 //обработка числа a
}

в ряде компиляторов может породить неточности при интерпретации данных. Например, этот код может прочитать как последнее значение завершающий перевод строки в файле, благодаря чему последнее прочитанное значение «удвоится».

Итак, убираем или комментируем

setlocale(LC_ALL,"Rus"); 

и всё заработало :)

15.10.2015, 15:55 [7791 просмотр]


К этой статье пока нет комментариев, Ваш будет первым

Понравилась статья? Поделить с друзьями:
  • Fs1370 ошибка 7990
  • Free fire ошибка загрузка прервана
  • Fragment ошибки на порту d link
  • Free fire ошибка даты и времени
  • Free fair ошибка сети