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

Обращение к функции - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 5.00
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
09.09.2012, 16:07     Обращение к функции #1
Здраствуйте!
Написал программу которая должна считать количество строчек в файле ( без пустых строчек ), пустыми строчками называются те которые содержат пробел, символ табуляции и непечатаемые символы.

Когда написал программу в функции int main, программа запустилась и правильно посчитала количество
строчек, но когда я решил перенести решение основной задачи в функцию
unsigned long NumberOfLine ( char NameOfFile ), возникла проблема : при запуске программы мне предлагается ввести имя файла с расширением, после его ввода программа завершает свою работу!

Вопрос : что я зделал не так ? подозреваю ошибка в обращении с функцией

вот код :
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
#include <iostream>
#include <fstream>
#include <clocale>
 
using namespace std;
 
 
unsigned long NumberOfLine ( char NameOfFile );
char fileName[255];
 
int main()
{
    setlocale(LC_CTYPE, "Russian");
    cout<<" Enter file name : ";
    cin>> fileName; 
    unsigned long NumberOfline ( char fileName ); // почему игнорит ету строчку ? как исправить ?
 
    return 0;
}
 
unsigned long NumberOfLine ( char NameOfFile )
{
    unsigned long numberOfLines = 0;
    char string[512];
 
    ifstream fin( fileName );
    if (fin)
    {
        while ( !fin.eof()  )
        {
            fin.getline(string ,513 , '\n');
                fin.ignore(1,'\t');
            fin.ignore(1,'\n');
            fin.ignore(1,' ');
            ++numberOfLines;
        } 
     
    }
    else
     cout<< " File: " << fileName << " is missing "; 
 
    fin.close();
 
    return numberOfLines;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2012, 01:34     Обращение к функции #21
Цитата Сообщение от 4ININ Посмотреть сообщение
Почти!
Код все строки считает.

Добавлено через 6 минут
Мне кажется, у вас подход неверный. Счётчик у вас сам по себе, а пропуск символов сам по себе. Логика должна быть такой: если в строке есть хотя бы один печатный символ, то увеличиваем счётчик. Через пропуски символов это не решить. Первую строку вы вообще не обрабатываете.

Добавлено через 1 час 12 минут
Такой вариант тоже работает:
Код
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
#include <iostream>
#include <fstream>
#include <clocale>
 
using namespace std;
 
 
unsigned long CalcOfString ( char *NameOfFile );
char fileName[255] = "main.cpp";
 
int main()
{
    setlocale(LC_CTYPE, "Russian");
    //cout<<" Enter file name : ";
    //cin>> fileName; 
    CalcOfString ( fileName );
    system("pause");
    return 0;
}
 
unsigned long CalcOfString ( char *NameOfFile )
{
    unsigned long numberOfLines = 0;
    char string[512];
 
    ifstream fin( fileName );
    if (fin)
    {
        while ( !fin.eof()  )
        {
            char ch;
            int flag = 0;
            while ( (ch = fin.peek()) != EOF ) 
            {
                if (ch != ' ' && ch != '\t' && ch != '\n')  
                {
                        ++numberOfLines;
                        flag = 1;
                        fin.ignore(255, '\n');
                        break;
                }
                fin.ignore(1);
            }
            
            //fin.getline(string ,513);
            
            /*{fin.ignore(1,'\n');    }
            while ( fin.peek() == '\t' )
            {fin.ignore(1,'\t');    } 
            while ( fin.peek() == ' ' )
                {fin.ignore(1,' ');}
            ++numberOfLines;
 
            cout<<string<<endl;*/
        }    
    }
    else
     cout<< " File: " << fileName << " is missing "; 
 
    fin.close();
    cout<<" \n"<<numberOfLines<<" "<<endl;
    
    return numberOfLines;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
11.09.2012, 19:01  [ТС]     Обращение к функции #22
Прикол! я такойже алгоритм создал, у меня даже строка
C++
1
if (ch != ' ' && ch != '\t' && ch != '\n')
была, но я реализовал ее через getline() а потом get(), в результате пошол от обратного и написал новый код ( который видели уже )

а зачем нужна переменная flag?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2012, 19:36     Обращение к функции #23
Цитата Сообщение от 4ININ Посмотреть сообщение
а зачем нужна переменная flag?
Забыл убрать. Сначала у меня ++numberOfLines; стояло после if и потому нужен был флаг, а потом перенёс, а флаг убрать забыл.
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
11.09.2012, 20:08  [ТС]     Обращение к функции #24
Подведём итог=)

Итак получается вышло 2 проги, с разными алгоритмами но с одинаковым результатом, одна прога использует метод "в лоб" а вторая идет методом "от обратного"
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2012, 20:13     Обращение к функции #25
Цитата Сообщение от 4ININ Посмотреть сообщение
Итак получается вышло 2 проги, с разными алгоритмами но с одинаковым результатом, одна прога использует метод "в лоб" а вторая идет методом "от обратного"
Из каких постов проги? Если имеется ввиду два моих кода, то алгоритм там одинаковый: перебор символов в строке и, при встрече с печатным символом, счётчик непустых строк увеличивается. Реализация алгоритмов разная.
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
11.09.2012, 20:16  [ТС]     Обращение к функции #26
Твоя и моя ( последние варианты )
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2012, 20:22     Обращение к функции #27
Цитата Сообщение от 4ININ Посмотреть сообщение
Твоя и моя ( последние варианты )
Последний вариант - это вот этот?
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
#include <fstream>
#include <clocale>
 
using namespace std;
 
 
unsigned long CalcOfString ( char *NameOfFile );
char fileName[255];
 
int main()
{
    setlocale(LC_CTYPE, "Russian");
    cout<<" Enter file name : ";
    cin>> fileName; 
    CalcOfString ( fileName );
    return 0;
}
 
unsigned long CalcOfString ( char *NameOfFile )
{
    unsigned long numberOfLines = 0;
    char string[512];
 
    ifstream fin( fileName );
    if (fin)
    {
        while ( !fin.eof()  )
        {
            fin.getline(string ,513);
                        while ( fin.peek() == '\n' )
            {fin.ignore(1,'\n');    }
            while ( fin.peek() == '\t' )
            {fin.ignore(1,'\t');    } 
            while ( fin.peek() == ' ' )
                {fin.ignore(1,' ');}
            ++numberOfLines;
 
            cout<<string<<endl;
        }    
    }
    else
     cout<< " File: " << fileName << " is missing "; 
 
    fin.close();
    cout<<" \n"<<numberOfLines<<" "<<endl;
    
    return numberOfLines;
}
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
11.09.2012, 20:27  [ТС]     Обращение к функции #28
получается да, но ее осталось допилить в проверке первой строки, и ты потерял
C++
1
#include <iostream>
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2012, 20:32     Обращение к функции #29
Объяснить можете: в каком случае, в этом коде, происходит ++numberOfLines; ?
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
11.09.2012, 20:42  [ТС]     Обращение к функции #30
Идет построчный перебор строк
C++
1
fin.getline(string ,513);
Далее в силу вступают поочередно цыклы которые сначала просматривают символ
C++
1
fin.peek()
и если удалось удовлетворить одно из условий :
C++
1
2
3
== '\n'
== '\t'
== ' '
идет игнор одного из символов ( исходя из условия )
C++
1
2
3
{fin.ignore(1,'\t');}
{fin.ignore(1,'\n');}
{fin.ignore(1,' ');}
так как все "ненужные" символы убрались остались только строки с нужными символами, соответственно и идет их подсчет.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
11.09.2012, 21:13     Обращение к функции #31
Какое значение выдаёт счётчик у вас в этом коде?

Добавлено через 8 минут
Я добавил одну строку (для остановки), и у меня выдаёт 50. Это что, правильный результат, по вашему? Добавьте строку и поставьте там три пробела. Выдаст 51. Код неверный в принципе.
Смотрите, как ваш код работает. Считывается строка: getline() читает до '\n', извлекает его из потока и отбрасывает. Потом проверяется следующий символ, если равен '\n', то пропускается один символ, если равен '\t', то же, если равен ' ', то же. После этого счётчик увеличивается. Далее getline() опять читает до '\n'. Значит, будут пропускаться только строки, в которых содержится только один '\n', или один '\t', или один ' '. Поставьте в пустой строке три пробела, и этот код посчитает эту строку, потому что пропустит только один пробел, а потом getline() считает два других и счётчик увеличится.

Добавлено через 9 минут
Счётчик у вас срабатывает при каждом считывании genline() и не зависит от того, что она считала, пустую (визуально) строку или нет. Расчёт на то, что пустое можно убрать через ignore() не срабатывает, потому что не известно сколько в пустой строке этого пустого. Может быть больше, чем одни пробел, или несколько знаков табуляции.
4ININ
2 / 2 / 0
Регистрация: 26.03.2012
Сообщений: 57
11.09.2012, 21:15  [ТС]     Обращение к функции #32
Яж специально поставил цыкл while, чтобы пропускались несколько символов а не if'ами все зделал... чтож буду работать над етим
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.09.2012, 02:15     Обращение к функции
Еще ссылки по теме:

Обращение к функции, из другого CPP C++
C++ Возможно ли обращение к статической памяти функции извне?
Обращение потока к функции-члену класса C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
12.09.2012, 02:15     Обращение к функции #33
Цитата Сообщение от 4ININ Посмотреть сообщение
Яж специально поставил цыкл while, чтобы пропускались несколько символов
Тогда, хотя-бы, поставьте это последним.
C++
1
2
while ( fin.peek() == '\n' )
            {fin.ignore(1,'\n');    }
И всё равно криво будет работать, потому что неизвестна последовательность в пустой строке пробельных символов. Представьте такую строку: ' '' ''\t''\t''\n' и такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while ( !fin.eof()  )
        {
            fin.getline(string ,513);
                        
            while ( fin.peek() == '\t' )
            {fin.ignore(1,'\t');    } 
            while ( fin.peek() == ' ' )
                {fin.ignore(1,' ');}
            while ( fin.peek() == '\n' )
            {fin.ignore(1,'\n');    }
            ++numberOfLines;
 
            cout<<string<<endl;
        }
Как он сработает? Пропустится два пробела, а остальное считается и счётчик увеличится. Потому что проверка на '\t' идёт перед проверкой на ' ', а в строке оказалось наоборот и т.д. Правильно код будет работать, если пробельные символы в строке идут в том же порядке, как и в коде. Любой другой порядок - и ошибка. Ваш код будет работать, то верно, то неверно, в зависимость от содержания строки. Ещё раз повторяю - подход неверный. Нужно не пробельные символы игнорировать, а искать в строке печатный символ, если есть, то увеличивать счётчик.
В предыдущем посте, я неправильно написал, что только один пробельный символ пропускается, но кривизну кода это не отменяет.

Добавлено через 30 минут
Вот такой код будет корректно работать:
Код
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
#include <iostream>
#include <fstream>
#include <clocale>
using namespace std;
 
unsigned long CalcOfString (char *NameOfFile);
char fileName[255] = "main3.cpp";
                                                                                                                                    
int main()
{
    setlocale(LC_CTYPE, "Russian");
    //cout<<" Enter file name : ";
    //cin>> fileName; 
    CalcOfString ( fileName );
            
    system("pause");
    return 0;
}
 
unsigned long CalcOfString (char *NameOfFile)
{
    unsigned long numberOfLines = 0;
    char string[512];
    
    ifstream fin(fileName);
    if (fin)
    {
       while ( fin.peek() == '\t' || fin.peek() == ' ' 
                                  || fin.peek() == '\n' 
                                  || fin.peek() == '\r') 
                    fin.ignore(1); 
        
        while (!fin.eof())
        {
            fin.getline(string, 512);
            ++numberOfLines;
            
            cout<< numberOfLines << ") " << string << endl;
                              
            
            while ( fin.peek() == '\t' || fin.peek() == ' ' 
                                       || fin.peek() == '\n' 
                                       || fin.peek() == '\r') 
                     fin.ignore(1); 
         }    
    }
    else  cout<< " File: " << fileName << " is missing "; 
 
    fin.close();
    
    cout<<" \n"<<numberOfLines<<" "<<endl;
    
    return numberOfLines;
}


Добавлено через 10 минуту
Но такое решение мне больше нравится:
Код
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
#include <iostream>
#include <fstream>
#include <clocale>
#include <cctype>
using namespace std;
 
unsigned long CalcOfString (char *NameOfFile);
char fileName[255] = "main3.cpp";
                                                                                                                                    
int main()
{
    setlocale(LC_CTYPE, "Russian");
    //cout<<" Enter file name : ";
    //cin>> fileName; 
    CalcOfString ( fileName );
            
    system("pause");
    return 0;
}
 
unsigned long CalcOfString (char *NameOfFile)
{
    unsigned long numberOfLines = 0;
    char string[512];
    
    ifstream fin(fileName);
    if (fin)
    {
       while ( !isgraph((unsigned char)fin.peek()) && !fin.eof())
                  fin.ignore(1); 
        
        while (!fin.eof())
        {
            fin.getline(string, 512);
            ++numberOfLines;
            
            cout<< numberOfLines << ") " << string << endl;
                     
            
            while ( !isgraph((unsigned char)fin.peek()) && !fin.eof())
                       fin.ignore(1); 
         }    
    }
    else  cout<< " File: " << fileName << " is missing "; 
 
    fin.close();
    
    cout<<" \n"<<numberOfLines<<" "<<endl;
    
    return numberOfLines;
}
Yandex
Объявления
12.09.2012, 02:15     Обращение к функции
Ответ Создать тему
Опции темы

Текущее время: 16:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru