Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.70
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 442
#1

Не работает scanf в цикле - C++

23.12.2011, 03:20. Просмотров 4105. Ответов 21
Метки нет (Все метки)

в коде
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
  int n,ip;
  printf("2-mernoe DPF\n");
  do {
  printf("\n 1-iz faila,  2-test,   0- Vixod\n");
  scanf("%d",&ip);
  if (ip==0) continue;
  if (ip==1) fileDPF();
  if (ip==2) testDPF();
           fflush(stdin);
    } while (ip!=0);
  return 0;
}
я рассчитывал на выход из цикла при вводе ip=0 (стандартное меню консольных программ)
Но получается фигня: 2й, 3й и следующие разы scanf просто не работает.
Т.е. значение ip остается=значению 1-го ввода. Естественно цикл крутится до бесконечности.
Наученный горьким опытом вставил fflush(stdin); в надежде доп.очистки входного потока,
но мертвому эти припарки не помогли.
Вот уж не ожидал такую гадость в простой проге
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.12.2011, 03:20
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не работает scanf в цикле (C++):

Scanf в цикле - C++
#include<stdio.h> #include<stdlib.h> #include<math.h> int main() { int n,i,k; double a,r;

Функция scanf() неправильно работает - C++
#include <stdio.h> #include <conio.h> #include <math.h> int main() { unsigned char c1, c2; bool b=true; while (b==true)...

Не работает программа через printf и scanf - C++
Нужно написать программу, которая бы выводила таблицу через printf и scanf, которые бы находились в циклах и данные заносились бы в массивы...

Не работает if в цикле while - C++
Определить, является ли натуральное N (вводить с клавиатуры) степенью числа 4 или нет. Результат вывести на экран и записать в файл. Вот...

Не работает printf без \n в цикле for - C++
Вообще задача: выводить процент завершения процесса без перехода на новую строку и без мигания курсора. В одной функции в цикле while...

Как работает рекурсия в цикле - C++
Всем привет! Подскажите пожалуйста как работает рекурсия в цикле, типа вот такого bool test(long long value,int n) { bool res =...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alkagolik
Заблокирован
23.12.2011, 05:15 #16
читайте, пробуйте
код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
 
struct ShortComplex
{
     //для имитации комплексного числа (спектр)
     double re, im;
};
 
void dpf2(float **x, ShortComplex **X, int L1,int L2)
{//вычисление прямого дискретного преобразования Фурье
 //прямым методом. Число операций порядка N*N
    double t;
 
    for ( int k1 = 0; k1 < L1; ++k1 )
        for ( int k2 = 0; k2 < L2; ++k2 ) {
 
            X[ k1 ][ k2 ].re = 0;
            X[ k1 ][ k2 ].im = 0;
 
            for ( int i = 0; i < L1; ++i )
                for (int j = 0; j < L2; ++j) {
                    t = 2. * M_PI * i * k1 / L1+2. * M_PI * j * k2 / L2;
                    X[ k1 ][ k2 ].re += x[ i ][ j ] * cos( t );
                    X[ k1 ][ k2 ].im += x[ i ][ j ] * sin( t );
                }
        }
}
 
void testDPF()
{//формирует тестовый временной сигнал x[i][j]=i если i>L1/2,j>L2/2 для ДПФ
//и выполняет ДПФ, результат в массиве X
    int L1, L2; //кол-во точек дискретизации по X и по Y
 
    printf( "L1=?, L2=?\n" );
    scanf( "%i%i", &L1, &L2 );
 
    float **x;
    ShortComplex **X;
    /***тут вы неверно выделяли память***/
    x = new float* [ L1 ]; 
    X = new ShortComplex* [ L1 ];
    
    /***тут были пропущены скобки***/
    for ( int i = 0; i < L1; ++i ) {
        x[ i ] = new float[ L2 ];
        X[ i ] = new ShortComplex[ L2 ];
    }
    printf("x=\n");
 
    for ( int i = 0; i < L1; ++i ) {
        for ( int j = 0; j < L2; ++j ) {
            if ( i >= L1/2. && j >= L2/2. )
                x[ i ][ j ] = 1.;
            else
                x[ i ][ j ] = 0;
            printf("%6.3f ",x[i][j]);
        }
        printf("\n");
    }
 
    dpf2( x, X, L1, L2 );
    printf( "\nSpectr X\n" );
 
    for ( int i = 0; i < L1; ++i ) {
        for ( int j = 0; j < L2; ++j )
            printf( "(%7.4f %7.4f) ", X[ i ][ j ].re, X[ i ][ j ].im);
        printf("\n");
    }
 
    for ( int i = 0; i< L1; ++i ) {
        delete x[ i ];
        delete X[ i ];
    }
    delete [] x;
    delete [] X;
}
 
void fileDPF()
{//читает тестовый временной сигнал x[i][j] из файла
 //и выполняет ДПФ, результат в массиве X
    int L1, L2;
    FILE * f = fopen( "dan.txt","r" );
    if ( f == NULL ) {
        printf( "faila dan.txt net\n" );
        return;
    }
 
    fscanf( f,"%i%i", &L1, &L2 );
 
    if ( ( L1 < 2 )|| ( L2 < 2 ) ) {
        printf("neverno L1 ili L2\n");
        return;
    }
 
    float **x;
    ShortComplex **X;
    /***тут вы неверно выделяли память***/
    x = new float* [ L1 ];
    X = new ShortComplex* [ L1 ];
 
    for ( int i = 0; i < L1; ++i ) {
        x[ i ] = new float[ L2 ];
        X[ i ] = new ShortComplex[ L2 ];
    }
 
    for (int i = 0; i < L1; ++i ) {
        for ( int j=0; j < L2; ++j ) {
            if ( ( i >= L1/2. ) && ( j >= L2/2. ) )
                x[ i ][ j ] = i;
            else
                x[ i ][ j ] = 0;
            printf("%6.3f ",x[i][j]);
        }
        printf("\n");
    }
    dpf2( x, X, L1, L2 );
    printf( "\nSpectr X\n" );
 
    for ( int i = 0; i < L1; ++i )  {
        for (int j = 0; j < L2; ++j )
            printf( "Re=%7.4f Im=%7.4f\n", X[ i ][ j ].re, X[ i ][ j ].im);
        printf("\n");
    }
    for ( int i = 0; i < L1; ++i ) {
        delete x[ i ];
        delete X[ i ];
    }
    delete[]x;
    delete []X;
}
int main()
{//главная программа -вызывает по выбору пользователя прямое или обратное преобразование
 //прямое для сигнала x[i]=i; //обратное для
    int ip;
    printf("2-mernoe DPF\n");
    do {
        printf( "\n 1-iz faila,  2-test,   0- Vixod\n" );
        scanf( "%d", &ip );
        if ( ip == 1 )
            fileDPF();
        else if ( ip == 2 )
            testDPF();
    } while ( ip != 0 );
 
  return 0;
}
результат
Код
2-mernoe DPF

 1-iz faila,  2-test,   0- Vixod
2
L1=?, L2=?
5
2
x=
 0.000  0.000 
 0.000  0.000 
 0.000  0.000 
 0.000  1.000 
 0.000  1.000 

Spectr X
( 2.0000  0.0000) (-2.0000  0.0000) 
(-0.5000 -1.5388) ( 0.5000  1.5388) 
(-0.5000  0.3633) ( 0.5000 -0.3633) 
(-0.5000 -0.3633) ( 0.5000  0.3633) 
(-0.5000  1.5388) ( 0.5000 -1.5388) 

 1-iz faila,  2-test,   0- Vixod
0

Process returned 0 (0x0)   execution time : 17.293 s
Press ENTER to continue.
тест памяти
==21943== Memcheck, a memory error detector
==21943== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==21943== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==21943== Command: ./plus
==21943==
2-mernoe DPF

1-iz faila, 2-test, 0- Vixod
2
L1=?, L2=?
3
5
x=
0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 1.000 1.000

Spectr X
( 2.0000 0.0000) (-0.5000 -1.5388) (-0.5000 0.3633) (-0.5000 -0.3633) (-0.5000 1.5388)
(-1.0000 -1.7321) (-1.0827 1.2024) ( 0.5646 0.2514) (-0.0646 0.6146) ( 1.5827 -0.3364)
(-1.0000 1.7321) ( 1.5827 0.3364) (-0.0646 -0.6146) ( 0.5646 -0.2514) (-1.0827 -1.2024)
==21943== Mismatched free() / delete / delete []
==21943== at 0x4027919: operator delete(void*) (vg_replace_malloc.c:387)
==21943== by 0x8048A61: testDPF() (main.cpp:72)
==21943== by 0x8048DE7: main (main.cpp:143)
==21943== Address 0x42f90a8 is 0 bytes inside a block of size 20 alloc'd
==21943== at 0x4027F65: operator new[](unsigned int) (vg_replace_malloc.c:299)
==21943== by 0x8048873: testDPF() (main.cpp:46)
==21943== by 0x8048DE7: main (main.cpp:143)
==21943==
==21943== Mismatched free() / delete / delete []
==21943== at 0x4027919: operator delete(void*) (vg_replace_malloc.c:387)
==21943== by 0x8048A74: testDPF() (main.cpp:73)
==21943== by 0x8048DE7: main (main.cpp:143)
==21943== Address 0x42f90f0 is 0 bytes inside a block of size 80 alloc'd
==21943== at 0x4027F65: operator new[](unsigned int) (vg_replace_malloc.c:299)
==21943== by 0x804888E: testDPF() (main.cpp:47)
==21943== by 0x8048DE7: main (main.cpp:143)
==21943==

1-iz faila, 2-test, 0- Vixod
0
==21943==
==21943== HEAP SUMMARY:
==21943== in use at exit: 0 bytes in 0 blocks
==21943== total heap usage: 8 allocs, 8 frees, 324 bytes allocated
==21943==
==21943== All heap blocks were freed -- no leaks are possible
==21943==
==21943== For counts of detected and suppressed errors, rerun with: -v
==21943== ERROR SUMMARY: 6 errors from 2 contexts (suppressed: 17 from 6)

из теста видно что несмотря на работу программы где-то есть недочеты, бегло не заметил, вполне вероятно что стоит попробовать всю работу с память переписать в стиле Си. А по большому счету для этой программы использовать динамическую память не нужно. Подумайте сами, массив создается для выполнения расчета и тут же уничтожается, т.е. его не надо ни расширять и сужать... вполне себе можно сделать статический массив на стеке. В мейне или глобальный как бы по большому счету без разницы.
зы, я не переписывал код, я просто его выравнивал и по пути исправлял все что заметил. Потом скомилял и устранил все варнинги, ну а искать ошибки рантайма это уже ваша работа

Добавлено через 6 минут
Цитата Сообщение от eugrita Посмотреть сообщение
Хоть и стиль C, scanf у меня единственный в главной проге
а scanf и fscanf в функциях не в счет? вроде как stdin один на все задачи
0
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 442
23.12.2011, 05:30  [ТС] #17
удалил
C++
1
if (ip==0) continue;
не помогло.
В общем плюнул я на это дело. Убрал цикл do раз так
Теперь выполняется 1 раз с выбором по меню и завершается
0
alkagolik
Заблокирован
23.12.2011, 05:34 #18
Цитата Сообщение от eugrita Посмотреть сообщение
В общем плюнул я на это дело.
а вот это зря. Попробуйте все таки выделение\освобождение памяти переписать на Си, а в конце функций testDPF, fileDPF кинуть fflush().
0
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 442
23.12.2011, 05:38  [ТС] #19
интересный прием - тест памяти -никогда не был с ним знаком.
Как вы это делаете?

Добавлено через 3 минуты
Цитата Сообщение от alkagolik Посмотреть сообщение
а вот это зря. Попробуйте все таки выделение\освобождение памяти переписать на Си, а в конце функций testDPF, fileDPF кинуть fflush().
Ладно попробую. А сейчас спать - завтра к 9 -9.30 в УФМС за загранпаспортом бежать надо.
При такой жене как у меня особенно не распрограммируешься
0
alkagolik
Заблокирован
23.12.2011, 05:41 #20
Цитата Сообщение от alkagolik Посмотреть сообщение
Попробуйте все таки выделение\освобождение памяти переписать на Си
вот тест на память после того как я переписал работу с памятью в Си
Код
==22332== Memcheck, a memory error detector
==22332== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==22332== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==22332== Command: ./plus
==22332== 
2-mernoe DPF

 1-iz faila,  2-test,   0- Vixod
2
L1=?, L2=?
5
12
x=
 0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000 
 0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000 
 0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000  0.000 
 0.000  0.000  0.000  0.000  0.000  0.000  1.000  1.000  1.000  1.000  1.000  1.000 
 0.000  0.000  0.000  0.000  0.000  0.000  1.000  1.000  1.000  1.000  1.000  1.000 

Spectr X
(12.0000  0.0000) (-2.0000 -7.4641) ( 0.0000 -0.0000) (-2.0000 -2.0000) (-0.0000  0.0000) (-2.0000 -0.5359) ( 0.0000  0.0000) (-2.0000  0.5359) ( 0.0000  0.0000) (-2.0000  2.0000) ( 0.0000 -0.0000) (-2.0000  7.4641) 
(-3.0000 -9.2331) (-5.2430  3.4049) (-0.0000 -0.0000) (-1.0388  2.0388) ( 0.0000  0.0000) ( 0.0877  1.6728) (-0.0000 -0.0000) ( 0.9123  1.4049) (-0.0000 -0.0000) ( 2.0388  1.0388) (-0.0000 -0.0000) ( 6.2430 -0.3272) 
(-3.0000  2.1796) ( 1.8557  1.5028) (-0.0000  0.0000) ( 0.8633  0.1367) (-0.0000 -0.0000) ( 0.5973 -0.2293) ( 0.0000  0.0000) ( 0.4027 -0.4972) (-0.0000 -0.0000) ( 0.1367 -0.8633) (-0.0000  0.0000) (-0.8557 -2.2293) 
(-3.0000 -2.1796) (-0.8557  2.2293) (-0.0000 -0.0000) ( 0.1367  0.8633) ( 0.0000  0.0000) ( 0.4027  0.4972) ( 0.0000  0.0000) ( 0.5973  0.2293) (-0.0000 -0.0000) ( 0.8633 -0.1367) ( 0.0000  0.0000) ( 1.8557 -1.5028) 
(-3.0000  9.2331) ( 6.2430  0.3272) (-0.0000  0.0000) ( 2.0388 -1.0388) ( 0.0000 -0.0000) ( 0.9123 -1.4049) ( 0.0000  0.0000) ( 0.0877 -1.6728) (-0.0000 -0.0000) (-1.0388 -2.0388) ( 0.0000  0.0000) (-5.2430 -3.4049) 

 1-iz faila,  2-test,   0- Vixod
0
==22332== 
==22332== HEAP SUMMARY:
==22332==     in use at exit: 0 bytes in 0 blocks
==22332==   total heap usage: 12 allocs, 12 frees, 1,240 bytes allocated
==22332== 
==22332== All heap blocks were freed -- no leaks are possible
==22332== 
==22332== For counts of detected and suppressed errors, rerun with: -v
==22332== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6)
==22332== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 6)
0
darkknight2008
62 / 62 / 6
Регистрация: 16.10.2011
Сообщений: 200
23.12.2011, 14:18 #21
Первая кака, которую заметил.
C++
1
2
float **x;  ShortComplex **X;
   *x=new float[L1]; *X=new ShortComplex[L1];
**x - указатель на указатель, когда ты пишешь *x, то обращаешься к тому на что он указывает. А он не указывает ни на что! В данном случаем он указывает на случайную ячейку памяти, и вот в эту ячейку ты записываешь указатель на выделенную память.
Как я понял, там заводятся два двумерных массива.
Значит будет так:
Вместо твоего
C++
1
2
3
4
 *x=new float[L1]; *X=new ShortComplex[L1];
  for (int i=0;i<L1;i++)
    {x[i]=new float[L2]; X[i]=new ShortComplex[L2];}
  printf("x=\n");
Должно быть вот это:
C++
1
2
3
4
5
6
7
  x = new float *[L1];
  X = new ShortComplex *[L1];
  for (int i = 0; i < L1; i++)
  {
    x[i] = new float[L2];
    X[i] = new ShortComplex[L2];
  }
Добавлено через 41 минуту
Если требуется объянение твоей ошибки, то текстом не получится - слишком долго. Могу объяснить по Скайпу, тебе решать...
1
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 442
27.12.2011, 07:19  [ТС] #22
Спасибо. Ошибка именно в отсутствии * в new float * .Испроавил - все сбои памяти пропали
и scanf стал нормально в цикле читать ip.
Что за фигня - видимо неправильно заучил - в свое время взял с какого то сайта и некритически отнесся.
Всем участникам спасибо.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.12.2011, 07:19
Привет! Вот еще темы с ответами:

Условие в цикле do while работает не так, как ожидается - C++
Проблема в условие цикла. Вот Код.// ConsoleApplication4.cpp: определяет точку входа для консольного приложения. // #include...

Синтаксических и арифметических ошибок в цикле вроде как нет, но он не работает - C++
Вот условие задачи: Дафна инвестировала $100 под простые 10%. Другими словами, ежегодно инвестиция должна приносить 10%...

Выяснить почему после ввода первого элемента массива цикл не работает (std::cin в цикле for) - C++
Добрый день! Взялся за простой пример из книги Лафоре. #include &lt;iostream&gt; #include &lt;iomanip&gt; using namespace std; const...

Как работает "шаг цикла" в цикле for? - C++
Всем привет! Я в с++ новичек !! кому не сложно обьясните как работает &quot;шаг цикла&quot; в цикле for For(счетчик = значение; счетчик &lt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
27.12.2011, 07:19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru