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

Работаю с файлом *.txt. Прога ведет себя странно если последняя строка файла пуста. Почему так? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Разработать С + +-программу с использованием файлов (Фибоначчи) http://www.cyberforum.ru/cpp-beginners/thread730442.html
!!!!Помогите срочно!!!! Создать С + +-программу отображения на экране последовательности первых К чисел Фибоначчи, которые вычисляются по следующему правилу: F_1 = 1; F_2 = 1; F_n = F_ (n-1) + F_ (n-2). Полученные элементы последовательности отражать на экране монитора в строку через пробел и записывать в файл «LR_4_1.txt». После завершения записи в файл, закрыть его. Восстановить файл и...
C++ iconv Есть такая библиотека как iconv для преобразования кодировок http://www.cyberforum.ru/blogs/131347/blog533.html Стоит задача написать простенькую обвертку для преобразования utf8 в win1251 в плюсовом стиле вроде std::string utf8_to_win1251(const std::string& instr) Но вот не могу найти нормально руководства где описывалось что и как... http://www.cyberforum.ru/cpp-beginners/thread730430.html
Проверка многоугольника на выпуклость C++
Здравствуйте. Не заходит вырезано задача. Не могу понять, почему. Проверял на схожесть знаков ориентированные площади треугольников из точек. Код: #include <iostream> #include <vector> #include <algorithm>
C++ Перевод из 2-ой в 8-ую СС
Необходимо реализовать перевод чисел из двоичной в восьмеричную систему счисления.
C++ Матрица (Найти вектор B(l), каждый элемент которого равен среднему арифметическому элементов...) http://www.cyberforum.ru/cpp-beginners/thread730405.html
Задана матрица A(k,l). Найти вектор B(l), каждый элемент которого равен среднему арифметическому элементов соответствующего столбца матрицы А. Похожие темы http://www.cyberforum.ru/csharp-beginners/thread591028.html http://www.cyberforum.ru/turbo-pascal/thread515227.html мой код #include <iostream> #include <time.h> using namespace std;
C++ Составить процедуру, выполняющую сжатие массива удалением элементов, значение которых меньше заданного числа Составить процедуру, выполняющую сжатие массива удалением элементов, значение которых меньше заданного числа. Вывести на экран максимальное значение среди удалённых элементов. Решите пожалуйста, кто сможет. Я в программировании не шарю, а лабу надо сделать подробнее

Показать сообщение отдельно
veslogrebov
0 / 0 / 0
Регистрация: 06.11.2012
Сообщений: 9

Работаю с файлом *.txt. Прога ведет себя странно если последняя строка файла пуста. Почему так? - C++

13.12.2012, 17:19. Просмотров 346. Ответов 1
Метки (Все метки)

Добрый день! Помогите пожалуйста с небольшой проблемой.

Что хотел сделать: Есть текстовый файл, в нем содержатся любые последовательности символов разделенные пробельными символами (пробелом, табуляцией).
Хочу сделать, без использования сторонних библиотек, класс, объекты которого принимают С-строку из этого файла и строят двусвязный список слов (1 элемент - 1 слово), игнорируя символы пробелов и табуляции.
И в общем то все сделал и все работает, но только если последняя строка в файле содержит хоть какие то символы.
Если же последняя строка файла пуста, у меня происходит лишняя итерация цикла, в результате которой до того, как я достигну конца файла, прога повторно выводит на экран последний объект.
Т.е. вот выполняется в main() этот код:
C++
1
2
3
4
5
 do{
        fgets(str, 1000, fp); //беру строку из файла
        Sentence S(str); // передаю строку в конструктор
        S.Show(); // вывод списка слов
    }while ( !feof(fp) ); // пока не достигнут конец файла
Последняя строка файла в конструктор не передается, S.Show() показывает последний созданный объект со списком заново, и только потом я достигаю конца файла. А как игнорировать такую пустую строку?

вот прога полностью:
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
149
150
151
152
153
154
155
156
157
158
#include <stdio.h>
#include <conio.h>
#include <locale.h>
#include <string.h>
 
const int SIZE = 1000;
const int WORDLEN = 50;
 
bool Whitespace (char c); // Проверяет является ли симовол "с" пробельным или NULL-символом.
 
class Sentence
{
private:
    struct Word
    {
        char wd[WORDLEN];
        bool isStopWord;
        
        Word *next;
        Word *prev;
    };
 
    int wordsAmmount; // Количество слов в строке
 
public:
    Word *Begining;
    void Show();
    Sentence(char *str);
 
};
 
Sentence::Sentence(char *str)
{
    printf("Конструктор=================================\n"); 
    /* Проверим, есть ли вообще какие-либо слова в строке. 
    Если их нет, создаем особый тип объекта, содержащий один элемент списка c NULL символом в поле wd,
    с нулевым счетчиком слов wordsAmmount. */
    int size = strlen(str);
    bool empty = true;
    wordsAmmount = 0;
 
    int indexWordBegin = -1; // первая буква первого слова (если оно вообще есть) в строке
    for (int c = 0; c < size; c++)
    {
        if (!Whitespace(str[c]))
        {
                empty = false;
                indexWordBegin = c;
                break;
        }
 
    }
    if (empty) 
    { 
        Begining = new Word;
        Begining->prev = NULL;
        Begining->next = NULL;
        Begining->wd[0] = '\0';
        Begining->isStopWord = true;
 
        wordsAmmount = 0;
 
        printf("empty\n"); 
        return;
    }
 
    /* Если дошли до этого момента, значит строка не пуста. Создадим первый элемент списка, и сразу
    запишем туда первое слово (его первая буква сохранена в indexWordBegin) */
    Begining = new Word;
    Begining->prev = NULL;
    Begining->next = NULL;
 
    int indexWordEnd = -1; // Последняя буква первого слова
    for(int i = indexWordBegin ; !Whitespace(str[i]) ; i++)
    {
        Begining->wd[i - indexWordBegin] = str[i];
        indexWordEnd  = i;
    }
    Begining->wd[indexWordEnd - indexWordBegin + 1] = '\0';
 
 
    wordsAmmount++;
 
    // Проверим, не достигли ли мы конца строки
    if ( str[indexWordEnd+1] == '\0' ) return;
 
    /* Если не достигли конца строки, сканируем ее, находим слова, создаем для них новые элементы списка */
    Word *iTemp = Begining;
    int car; // сокр. carriage, общий указатель на символы строки
    while (1)
    { 
        for (car = indexWordEnd+1 ; Whitespace(str[car]) && str[car] != '\0' ; car++); // После всех итераций в car хранится индекс первой буквы следующего слова, либо символ конца строки.
        
        // Проверим, не достигли ли мы конца строки
        if (str[car] == '\0') return;
        
        // Значит car указывает на начало следующего слова. Создадим для него новый элемент списка.
        iTemp->next = new Word;
        iTemp->next->prev = iTemp;
        iTemp->next->next = NULL;
        iTemp = iTemp->next;
 
        // Запишем это слово в элемент списка
        for(int i = car ; !Whitespace(str[i]) ; i++)
        {
            iTemp->wd[i - car] = str[i];
            indexWordEnd  = i;
        }
        iTemp->wd[indexWordEnd - car + 1] = '\0';
 
        wordsAmmount++;
 
        // Проверим, не достигли ли мы конца строки
        if ( str[indexWordEnd+1] == '\0' ) return;
    }
}
 
void Sentence::Show()
{
    Word *iTemp = Begining; 
    while (iTemp->next != NULL)
    {
        printf ("%s \n",iTemp->wd);
        iTemp = iTemp->next;
    }
    printf ("%s \n",iTemp->wd); // вывод последнего элемента списка
}
 
int main()
{
    setlocale(LC_ALL, "russian");
 
    FILE *fp;
    fp = fopen("Text.txt", "r");
    
    char str[SIZE];
    do{
        fgets(str, 1000, fp);
        Sentence S(str);
        S.Show();
    }while ( !feof(fp) );
 
    getch();
    return 0;
}
 
bool Whitespace (char c)
{    
    // Функция проверяет является ли симовол "с" пробельным или NULL-символом. Если является - возвращает true
    // Коды пробельных символов:
    const int LF = 10;    // перевод строки
    const int CR = 13;    // возврат каретки
    const int SP = 32;    // пробел
    const int HT = 9;    // горизонтальная табуляция
 
    if (c == LF || c == CR || c == SP || c == HT || c == '\0') return true;
    else return false;
}
Вот тестовый файл Text.txt, должен лежать в корне проекта. Обратите внимание на 12-ю пустую строчку, из за нее все проблемы
C++
1
2
3
4
5
6
7
8
9
10
11
     aaaa!!!!    bbbb       cccc..
                dddd'd???? eeee
fffff
 
 
 
               
 
                    
                    
gggg                      hhhhhh            iiiiii
Вложения
Тип файла: txt Text.txt (147 байт, 1 просмотров)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru