В файл записан текст. Нужно вывести на экран все слова, которые заканчиваются такой буквой, на какую начинаются. Не использовать string. Не использовать STL и сторонние библиотеки
Строки в C++ могут быть представлены разными способами, отчего у начинающих часто возникают проблемы с понимаем разных примеров. Но как бы ни представлялась строка программистом — она всегда последовательность символов. Обычно со строками, как бы они ни были представлены, можно работать как с одномерными массивами. Это важное обстоятельство легко можно упускать из виду при недостатке опыта. Но если вы понимаете, что строками можно работать как с массивами, то и решать задачи становится резко легче.
Одна из проблем при работе со строковым представлением связана с выделением памяти для указателей, должных выполнять функции строк. При возможности не использовать указатели не нужно использовать указатели. Но иногда условием задачи может подразумеваться неиспользование удобных стредств для работы со строками (таких как std::string), что часто подразумевает использование в C++ строк в стиле C, но иногда это ещё означает, что строи должны быть только хранилищем и дополнительные строки создавать не нужно: что бы вы не использовали для строкового представления — это всегда выделение памяти с помощью new[] и работа delete [], а это долгие операции. Прямая работа с памятью — это всегда долго.
В этой статье показано решение задачи, в котором удачно избегается прямая работа с распределением памяти.
Задача:
В файл записан текст. Нужно вывести на экран все слова, которые заканчиваются такой буквой, на какую начинаются. Не использовать string. Не использовать STL и сторонние библиотеки.
Будем считать, что две одинакове буквы, имеющие разный регистр, одинаковые, а два одинаковых графических символа, принадлежащие разным языкам — разные (что латинская A и наша родная А — неодинаковы и т. д.). Можно, конечно, сделать регистронезависимое сравнение и сопоставление графисеских символов разных языков, но это немного раздует количество кода.
Первое действие — разработка некоторой стратегии решения. Задача может иметь уйму способов решений, но мы остановимся на одном. Можно посимвольно читать файл и по прочитанным символам составлять слово, после чего это слово проверять на равенство первой и последней буквы. Если равенство справедливо — то выводить слово на экран. Само по себе посимвольное чтение вполне можно использовать для разбиения на слова: для этого нужно только определиться, что считать разделителями. Прочитанное слово нужно где-то хранить. Для хранение достаточно объявить массив символов. Ничего придумывать не будем, дабы не осложнять сейчас то, что еще в принципе не особо-то и понимаем (если кто не понимает, конечно). Как-то нужно узнавать первый и последний символы слова. С первым проблем нет: если курсор, бегающий по строке, находится в начальной (нулевой) позиции и прочитан значащий символ-не_разделитель, то прочитанный символ — это первый символ; сложнее с последним символом слова. В примере я решил не мудрить и добавить одну переменную, в которую на каждой итерации будет записываться символ, если этот символ не является разделителем.
Вступление было написано для того, чтобы заложить базу понимания того, кода который я покажу.
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
//C++ mingw Выводим на экран все слова из файла, начинающиеся с той буквы, на которую заканчиваются
#include <iostream>
#include <fstream>
#include <windows.h>
usingnamespacestd;
//Это функция проверки на разделитель
boolis_separator(constchar&ch){
switch (ch)
{
case ' ':;//разрыв break здесь не нужен!
case',':;
case'\n':;
returntrue;
}
returnfalse;
}
intmain()
{
setlocale(LC_ALL,"");
SetConsoleOutputCP(866);
intch;//Для посимвольного чтения файла. Символы будут считываться в ch
intcount_=0;//Курсор для прочитанного слова. Номер символа в слове
charS[255]={};//Слово будет записываться в массив символов. Предполается размер слова не будет больше 255 символов
chart=0;//Последний прочитанный символ слова
ifstreamMyFile("M:\\test.txt");
if(MyFile.is_open()){
while((ch=MyFile.get())!=EOF){
if(is_separator(ch)){//Если встретили разделитель, проверяем существование слова
if(count_){//Если курсор не в стартовой точке, то слово есть
count_=0;//Ставим курсор на начало для нового слова
if(S[0]==t){//Если первый символ равен последнему символу слова, то выводим на экран S
cout<<S<<"\n";
}
for(inti=0;i<255;i++){//Очищаем от мусора массив S
S[i]=0;
}
}
else{//Если встретили не разделитель, то
t=char(ch);//Запоминаем сивол в t
S[count_]=char(ch);//Дописываем в конец S прочитй символ
count_++;//Двигаем курсор по массиву
}
}
}else{
cout<<"Файла не существует\n";
}
MyFile.close();
}
Код был проверен по файлу с текстом:
текст для проверки
слово барак кабак
капитан, налим, махал
Последним символов в файле должен быть любой разделитель, иначе последнее слово не попадёт на обработку. Это связано с тем, что для выборки символов используется int ch;, а не char ch. Целое (int) преобразовывается в char. Использование int вместо char обусловлено тем, что так можно нормально прочитать файл посимвольно. Вступлением уже обозначен общий принцип работы кода, поэтому, надеюсь, пример окажется понятен и полезен.
Добавить комментарий