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

Функция getline не считывает пробелы - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 25, средняя оценка - 4.84
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 13:41     Функция getline не считывает пробелы #1
Написал код программы для вывода из файла строк, где есть двузначные цифры. Пользовался функцией getline. Но указанные в процессе работы программы строки выводятся "слипшиеся" - без пробелов.

Вот код программы:

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
#include "stdafx.h"
#include "iostream"
#include "fstream"
//#include "stdio.h"
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
    // создание входного потока и открытие файла
    ifstream fin("c:\\projects\\text1.txt", ios::in);
    if (!fin)
    {
        cout << "Can't open input file" << endl;
        system("pause");
        return -1;
    } 
 
    char buf[255];
    char lim;
    int i = 0;
    while (!fin.eof())      // пока не конец файла
    {
        i = 0;
        cout<<endl;
        fin.getline(buf, 255, lim = '\n');  // считать одну строку
        while (buf[i])                      // рассмотреть каждый символ этой строки
        {
            if (buf[i] >= '1' && buf[i] < '100')    // если текущий символ - двузначная цифра
                cout << buf[i];                     // то начать выводить эту строку посимвольно
            i++;                                    // перепестить индекс массива buf вперед
        }
    }
    
    fin.close();
    fout.close();
    cout << endl;
    cout << endl;
    system("pause");
    return 0;
}
Можете подсказать, как с помощью этой функции считывать и пробелы. Или может другая функция существует?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
NoMasters
Псевдослучайный
1740 / 1083 / 70
Регистрация: 13.09.2011
Сообщений: 3,102
04.02.2012, 13:49     Функция getline не считывает пробелы #2
Цитата Сообщение от Gooman Посмотреть сообщение
buf[i] < '100'
Здесь ты неправ.
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 13:50  [ТС]     Функция getline не считывает пробелы #3
Цитата Сообщение от NoMasters Посмотреть сообщение
Здесь ты неправ.
Я знаю. Исправить нет проблем. Но как же считывать пробелы?!
NoMasters
Псевдослучайный
1740 / 1083 / 70
Регистрация: 13.09.2011
Сообщений: 3,102
04.02.2012, 14:00     Функция getline не считывает пробелы #4
Всё должно считываться, но в соответствии с if пробелы не выводятся.
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 14:01  [ТС]     Функция getline не считывает пробелы #5
Цитата Сообщение от NoMasters Посмотреть сообщение
Всё должно считываться, но в соответствии с if пробелы не выводятся.
Спасибо, теперь понятно. Буду исправлять.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 14:03     Функция getline не считывает пробелы #6
Gooman, это же не компилируемый код! Покажи в том виде, в котором компилируешь. А проблема не с считываением, а с выводом.

Добавлено через 36 секунд
опоздал
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 14:03  [ТС]     Функция getline не считывает пробелы #7
Цитата Сообщение от Kastaneda Посмотреть сообщение
Gooman, это же не компилируемый код! Покажи в том виде, в котором компилируешь. А проблема не с считываением, а с выводом.
У меня это компилируемый код. В этом самом виде и компилирую.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 14:06     Функция getline не считывает пробелы #8
Цитата Сообщение от Gooman Посмотреть сообщение
У меня это компилируемый код. В этом самом виде и компилирую.
fout в stdafx.h чтоли объявлен?
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 15:09  [ТС]     Функция getline не считывает пробелы #9
Цитата Сообщение от Kastaneda Посмотреть сообщение
fout в stdafx.h чтоли объявлен?
Нужно убрать строчку с закрытием файла fout.

Добавлено через 1 час 0 минут
Кто-нибудь может помочь? Уже по-разному пробовал и остановился на таком вот варианте. Но ничего не выводится.
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
#include "stdafx.h"
#include "iostream"
#include "fstream"
//#include "stdio.h"
using namespace std;
 
void readfile (char *buf, ifstream fin); // считывает содержимое файла в массив литер buf
 
int _tmain(int argc, _TCHAR* argv[])
{
    // создание входного потока и открытие файла
    ifstream fin("c:\\projects\\text1.txt", ios::in);
    if (!fin)
    {
        cout << "Can't open input file" << endl;
        system("pause");
        return -1;
    } 
 
    // создание выходного потока и открытие файла
    ofstream fout("c:\\projects\\text2.txt", ios::out);
    if(!fout)
    {
        cout << "Can't create output file" << endl;
        system("pause");
        return -1;
    }
 
    char buf[255];
    char lim;
    int i = 0;
    int good_str = 0; // 1, если строка содержит только двузначные цифры
    while (!fin.eof())      // пока не конец файла
    {
        good_str = 0;
        i = 0;
        cout<<endl;
        fin.getline(buf, 255, lim = '\n');  // считать одну строку
        while (buf[i])                      // рассмотреть каждый символ этой строки
        {
            if (buf[i] == '\n')
                continue;
 
            if (buf[i] >= '1' && buf[i] <= '9')             // если текущий символ - цифра
                if (buf[i+1] >= '0' && buf[i+1] <= '9')     // если следующий символ тоже цифра
                    if (buf[i+2] >= '0' && buf[i+2] <= '9') // если и  третий символ - цифра
                        good_str = 0;    // то строка нам не подходит
                    else 
                        good_str = 1;    // иначе число имеет 2 знака, строка подходит.
 
            else
                good_str = 0;
 
            i++;                                    // переместить индекс массива buf вперед
        }
        if (good_str)
            cout << buf;            
    }
    
 
    fin.close();
    fout.close();
    cout << endl;
    cout << endl;
    system("pause");
    return 0;
}
А если убрать строки 51 и 52, то начинает хоть что-то выводиться. Однако выводятся и строки, где есть трехзначные цифры. Что нужно исправить, помогите, пожалуйста
Напомню задание: мне надо было записать в другой файл (вывести на экран) строки, где есть только двухзначные цифры. Ну в строках, естественно, не только цифры, а просто предложения любые.
Том Ардер
Модератор
 Аватар для Том Ардер
3644 / 2263 / 276
Регистрация: 15.06.2009
Сообщений: 3,975
04.02.2012, 15:39     Функция getline не считывает пробелы #10
Цитата Сообщение от Gooman Посмотреть сообщение
двузначные цифры
Цифры и Числа - суть разные вещи
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool good_str = false;
while (buf[i] && !good_str)  // рассмотреть каждый символ этой строки 
{ 
  if ( buf[i] == '\n')
     continue; 
  good_str = isdigit(buf[i]) && isdigit(buf[i+1]) && !isdigit(buf[i+2]);  // именно двузначное число
  i++;
} 
 
if (good_str)
{
   cout << buf << endl;
   fout << buf<< endl;
}
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 15:53     Функция getline не считывает пробелы #11
Цитата Сообщение от Gooman Посмотреть сообщение
А если убрать строки 51 и 52, то начинает хоть что-то выводиться. Однако выводятся и строки, где есть трехзначные цифры. Что нужно исправить, помогите, пожалуйста
Когда находишь нужную строку, добавь выход из цикла while(), т.е.
C++
1
2
3
4
 else {
   good_str = 1;    // иначе число имеет 2 знака, строка подходит.
   break;
}
иначе строка смотриться дальше и значение good_str скорее всего меняется.
Еще перед просмотром очередного символа проверь, является ли i валидным, т.е. ну будет ли выхода за пределы массива. Если i будет равно strlen(buf)-1, то в условии if(buf[i + 2] ...) будет выход за пределы массива.

Еще нет смысла проверять является ли текущий символ символом '\n', т.к. getline() не записывает его в строку.

Так же советую использовать фигурные скобки во всех if'ах (а так же в for'ах и while'ях). Это придает бОльшую читабельность и позволяет легко редактировать код.
Например в 51 строке создается впечатление, что else относится к if'у из 44 строки, а в действительности из 45ой (хотя это скорее вопрос правильного форматирования кода)
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 15:58  [ТС]     Функция getline не считывает пробелы #12
Том Ардер, ну вы очень легко поступили, пользуясь встроенной нестандартной функцией. А как без нее сделать?
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 16:00     Функция getline не считывает пробелы #13
Цитата Сообщение от Gooman Посмотреть сообщение
пользуясь встроенной нестандартной функцией
Это стандартная функция. Кстати в коде Том Ардер занчение i тоже не проверяется.
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 16:00  [ТС]     Функция getline не считывает пробелы #14
Цитата Сообщение от Kastaneda Посмотреть сообщение
Это стандартная функция. Кстати в коде Том Ардер занчение i тоже не проверяется.
Стандартная функция чего? Visual studio?
И если там break поставить, то строка дальше смотреться не будет. Т.е. если встретили где-то в первом месте число 25, прервали цикл. А в той же строке дальше может идти число 325. Получается, что выведется ненужная строка.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 16:07     Функция getline не считывает пробелы #15
Цитата Сообщение от Gooman Посмотреть сообщение
Стандартная функция чего? Visual studio?
Языков С/С++.
isdigit()

Добавлено через 3 минуты
Цитата Сообщение от Gooman Посмотреть сообщение
И если там break поставить, то строка дальше смотреться не будет. Т.е. если встретили где-то в первом месте число 25, прервали цикл. А в той же строке дальше может идти число 325. Получается, что выведется ненужная строка.
Угу, тогда смотри еще предыдущий символ)
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 16:08  [ТС]     Функция getline не считывает пробелы #16
Цитата Сообщение от Kastaneda Посмотреть сообщение
Языков С/С++.
isdigit()

Добавлено через 3 минуты

Угу, тогда смотри еще предыдущий символ)
Хотя, в задании не сказано, что должны в строке быть только двузначные цифры. Написано, что "только те строки, где есть двузначные цифры". Значит, там могут быть и двухзначные, и трехзначные одновременно. Раз isdigit есть даже с C, то буду пользоваться ей.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 17:38     Функция getline не считывает пробелы #17
Цитата Сообщение от Gooman Посмотреть сообщение
Хотя, в задании не сказано, что должны в строке быть только двузначные цифры. Написано, что "только те строки, где есть двузначные цифры". Значит, там могут быть и двухзначные, и трехзначные одновременно.
Да. Я твое замечание понял по другому, а ты мое не понял.

Цитата Сообщение от Gooman Посмотреть сообщение
И если там break поставить, то строка дальше смотреться не будет. Т.е. если встретили где-то в первом месте число 25, прервали цикл. А в той же строке дальше может идти число 325. Получается, что выведется ненужная строка.
Смотри, в строке может быть число 325, тогда когда i будет указывать на 3, то good_str будет 0, а i увеличится на 1. При следующей итерации i будет указывать на 2, далее будет идти 5 а потом например пробел и good_str станет равным 1, как будто это двузначное число, хотя это не так. Поэтому нужно смотреть еще предыдущий символ, чтоб он не был цифрой.

Добавлено через 1 час 25 минут
Если компилятор с поддержкой С++11, то можно сделать так:
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
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
 
int main()
{
    std::string file_name("main.cpp");
    std::ifstream in(file_name);
    if (!in) {
        std::cout << "Can't open file " << file_name << std::endl;
        return 1;
    }
 
    std::string str;
    std::regex pattern("(^|[^0-9])[0-9]{2}(?![0-9])");
 
    while (std::getline(in, str)) {
        if (std::regex_search(str.begin(), str.end(), pattern)) {
            std::cout << str << std::endl;
        }
    }
 
    return 0;
}
не часто пользуюсь регулярками, поэтому подозреваю, что шаблон можно сделать более красиво
Gooman
10 / 10 / 0
Регистрация: 03.10.2010
Сообщений: 350
04.02.2012, 17:40  [ТС]     Функция getline не считывает пробелы #18
Kastaneda, я вообще пользовался только СИ, а это углубленный с++ какой-то. Мне ведь стандартными средствами с++ надо сделать.
Том Ардер
Модератор
 Аватар для Том Ардер
3644 / 2263 / 276
Регистрация: 15.06.2009
Сообщений: 3,975
04.02.2012, 17:47     Функция getline не считывает пробелы #19
Цитата Сообщение от Kastaneda Посмотреть сообщение
Смотри, в строке может быть число 325, тогда когда i будет указывать на 3, то good_str будет 0, а i увеличится на 1. При следующей итерации i будет указывать на 2, далее будет идти 5 а потом например пробел и good_str станет равным 1, как будто это двузначное число, хотя это не так. Поэтому нужно смотреть еще предыдущий символ, чтоб он не был цифрой.
Это тоже не спасает: для цифры 5 надо смотреть уже два предыдущих символа.
Выход в другом: считать количество цифр

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char buf[256], *pbuf = buf;
bool good_str = false;
 
while( *pbuf && !good_str )
{
    int ndigits = 0;
    char pdig = pbuf;
 
    while( isdigit(*pdig) )
    {
        pdig++;
    }
 
    ndigits = pdig - pbuf;  // pdig или =pbuf, или указывает на символ после последней цифры
 
    good_str = ndigits == 2;
 
    pbuf += ndigits + 1;  // пропустить число или перейти к следующему символу
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.02.2012, 17:55     Функция getline не считывает пробелы
Еще ссылки по теме:

Программа не считывает пробелы C++
Функция getline(cin,.) C++
C++ Почему getline не считывает строку при первом проходе цикла?
Getline не считывает строку целиком C++
C++ Почему stream.getline считывает до пробела?

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

Или воспользуйтесь поиском по форуму:
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4248 / 2780 / 219
Регистрация: 12.12.2009
Сообщений: 7,109
Записей в блоге: 1
Завершенные тесты: 1
04.02.2012, 17:55     Функция getline не считывает пробелы #20
Цитата Сообщение от Том Ардер Посмотреть сообщение
Это тоже не спасает: для цифры 5 надо смотреть уже два предыдущих символа.
Одного предыдущего символа и двух следующих будет достаточно, т.к. если число из 3х и более цифр, то строка уже не подходит.
Yandex
Объявления
04.02.2012, 17:55     Функция getline не считывает пробелы
Ответ Создать тему
Опции темы

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