Как считать пробелы в c из файла
Перейти к содержимому

Как считать пробелы в c из файла

  • автор:

Как считать пробелы в c из файла

Файл написан псевдографикой, где пустое место обозначено пробелом, при чтении с помощью ifstream пробелы не читаются, никак, а необходимо считывать по одному символу из файла в массив в том числе и пробелы
Помогите пожалуйста, объясните как их считывать

Форумчанин
Регистрация: 31.08.2009
Сообщений: 161

с помощью ifstream пробелы не читаются, никак, а необходимо считывать по одному символу из файла в массив в том числе и пробелы

в смысле не считываются?

ifstream file("file.txt"); char s; file.get(s); cout
ThisIzGame
Посмотреть профиль
Найти ещё сообщения от ThisIzGame

Регистрация: 13.08.2010
Сообщений: 2

большое спасибо, незнаю почему об этом нигде не пишут т.к. неделя поиска ничего не дала
извиняюсь за тупой вопрос =)

Форумчанин
Регистрация: 26.04.2010
Сообщений: 328

Да ладненько, гуглится за минуту =)

Сообщение : answered Sep 22 '08 at 19:55, в самом конце.

Используй гугль, будь счастлив
hackme@yandex.ru
Блог об archlinux
Последний раз редактировалось ozo; 13.08.2010 в 23:29 .

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение файла PastoriXx C++ Builder 8 23.02.2012 08:13
чтение из файла Sparky Общие вопросы C/C++ 5 13.04.2010 18:47
Чтение из файла. Си. MAKEDON Помощь студентам 1 17.08.2009 16:42
Чтение из файла Arkuz Общие вопросы Delphi 14 08.10.2008 19:52
Чтение файла Stanislav Общие вопросы Delphi 18 24.11.2007 20:45

Считывание из файла вместе с пробелами

Здравствуйте, у меня есть проблема. Я работаю над проектом и мне нужно считать информацию из файла в массив char. Но во время считывание, ни один из мне известных методов не считывает пробелы. Предварительная замена пробелов для последующей обратной замены не возможна в реализации. Как разобраться с проблемой невозможности преобразований типов const char и char?
Вот кусочек наработок, надеюсь он хоть чем-то прояснит ситуацию (вариант не доведён до ума):

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
void FindName() { char *Name = new char[10]; printf("\n\n-ПОИСК ИНФОРМАЦИИ ЗА ИМЕНЕМ-\n"); printf("Имя:\n"); fgetc(stdin); fgets(Name, 30, stdin); printf("\n------------------------\n"); printf(":\n"); char All[100]; fstream file; file.open("0.txt", ios::in); int i = 0; while (!file.eof()) { file >> All[i]; i++; } file.close(); All[i - 1] = 0; cout  All; cout  endl; }

Лучшие ответы ( 2 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Считывание вместе с пробелами
Столкнулся с одной проблемой при считывании из файла программа считает пробелы символами.

Считывание из файла с пробелами
Здравствуйте. Нужно считать из файла сообщение, в котором заранее известны что будут пробелы.

Считывание файла с пробелами.
Подскажите, пожалуйста, как при считывание текстового файла сохранить пробелы между словами. Темы.

Чтение строки вместе с пробелами
Всем привет. string str1;cin>>str1; int len1 = str1.length(); cout<<len1; string str1="Hello.

7595 / 6418 / 2924
Регистрация: 14.04.2014
Сообщений: 27,946

ЦитатаСообщение от _Sora_ Посмотреть сообщение

ни один из мне известных методов не считывает пробелы
fgets() берёт строку целиком.
Регистрация: 14.03.2014
Сообщений: 249
std::getline
Регистрация: 30.10.2017
Сообщений: 34

Да но без пробелов. Если данные были "1 1 1" то массив складывается с 3 элементов "1"

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

ЦитатаСообщение от Pechkin80 Посмотреть сообщение

std::getline

Можно пожалуйста по подробнее? Если я не ошибаюсь, getline считывает строку string, а мне нужен массив char.

3434 / 2813 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
Регистрация: 14.03.2014
Сообщений: 249

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Указатель на файловый поток std::ifstream m_fs; // в классе объявляем { const char * c_delimiter = "/n"; std::stringstream * istrstm = NULL; std::string lexema = ""; m_fs.open(m_inputdata.fname.c_str()); if (m_fs.is_open()) { istrstm = new std::stringstream(); *istrstm  m_fs.rdbuf(); m_fs.close(); } if (istrstm) { while (getline((*istrstm),lexema,c_delimiter) != 0) { if (lexema.empty()) { continue; } /// }

3802 / 2354 / 413
Регистрация: 09.09.2017
Сообщений: 10,208

ЦитатаСообщение от _Sora_ Посмотреть сообщение

char *Name = new char[10];
fgets(Name, 30, stdin);

Не делайте так больше. Вы разрешаете, явным образом разрешаете, выход за пределы массива. В лучшем случае это сразу приведет к сегфолту.
Согласен с nmcf: fgets берет строку целиком со всеми пробелами, табуляциями, спецсимволами, даже финальным переводом строки.

155 / 137 / 46
Регистрация: 15.02.2010
Сообщений: 750

Лучший ответ

Сообщение было отмечено _Sora_ как решение

Решение

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#include #include #include using namespace std; int main() { ifstream f("name.txt"); //читаем всё в строку s string s="",s1; while (getline(f, s1)) s += s1; f.close(); //s - фактически есть динамический символьный массив. //но, eсли Вам нужен отдельный char-массив, то: char *c = new char[s.length()]; for (int i = 0; i  s.length(); i++) c[i] = s[i]; cout  s  endl  c  endl; system("pause"); return 0; }

Регистрация: 30.10.2017
Сообщений: 34

ЦитатаСообщение от COKPOWEHEU Посмотреть сообщение

Не делайте так больше. Вы разрешаете, явным образом разрешаете, выход за пределы массива. В лучшем случае это сразу приведет к сегфолту.

Простите, а как мне поступить если я не знаю сколько будет занимать Name?

ЦитатаСообщение от COKPOWEHEU Посмотреть сообщение

Согласен с nmcf: fgets берет строку целиком со всеми пробелами, табуляциями, спецсимволами, даже финальным переводом строки.

Простите, но почему тогда в итоге у меня массив char складается только из элементов которые не включают пробелы.

7595 / 6418 / 2924
Регистрация: 14.04.2014
Сообщений: 27,946

ЦитатаСообщение от _Sora_ Посмотреть сообщение

как мне поступить если я не знаю сколько будет занимать Name?
Ну какой-то разумный предел предполагается же?

ЦитатаСообщение от _Sora_ Посмотреть сообщение

почему тогда в итоге у меня массив char складается только из элементов которые не включают пробелы
Что в файле?
Регистрация: 30.10.2017
Сообщений: 34

ЦитатаСообщение от nmcf Посмотреть сообщение

Что в файле?
1_1_1 _-пробел
1370 / 593 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
#include
#include

ifstream file(FileName); //открыть для чтения в текстовом режиме
file.getline(S,len);

S - символьная строка
len - максимальная длина строки.

И мне, например, не ясно. Вы хотите по строкам: каждая строка - это массив, или просто весь файл в символьный массив? Судя по коду, хотели построчно.

Регистрация: 30.10.2017
Сообщений: 34

ЦитатаСообщение от daslex Посмотреть сообщение

И мне, например, не ясно. Вы хотите по строкам: каждая строка - это массив, или просто весь файл в символьный массив? Судя по коду, хотели построчно.

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

7595 / 6418 / 2924
Регистрация: 14.04.2014
Сообщений: 27,946
Тогда используй fscanf() для первого варианта или >>.
1370 / 593 / 199
Регистрация: 02.08.2011
Сообщений: 2,882

Лучший ответ

Сообщение было отмечено _Sora_ как решение

Решение

Как-то мутно всё очень. Сильно напоминает необходимость использования массива структур и незнание о массиве структур.
Вот то, что Вы описываете - это массив структур, хранимый в файле.

Для бинарного режима

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
#include #include using namespace std; /*Структура должна соответствовать структуре данных, хранимых в файле*/ struct MyStruct{ char FirstName[155]; //Это символьная строка в 155 символов char LastName[155]; //Это символьная строка в 155 символов char phone[25]; //Это символьная строка в 25 символов }; int main(){ const char* FName = "file.txt"; //Это Ваш файл MyStruct X[3]; ifstream file("file", ios::binary); file.read((char*)&X, sizeof(X)); file.close(); /*Ну, тут вообще цикл нужен, я для упрощения*/ cout  X[0].FirstName  ' '  X[0].LastName  ' '  X[0].phone  '\n'; cout  X[1].FirstName  ' '  X[1].LastName  ' '  X[1].phone  '\n'; cout  X[2].FirstName  ' '  X[2].LastName  ' '  X[2].phone  '\n'; }

Для текстового режима

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
#include #include using namespace std; struct MyStruct{ char FirstName[155]; //Это символьная строка в 155 символов char LastName[155]; //Это символьная строка в 155 символов char phone[25]; //Это символьная строка в 25 символов }; int main(){ const char* FName = "file.txt"; //Это Ваш файл MyStruct X[3]; ofstream of("file"); MyStruct T[3] = { { "Ivanov", "Petr", "778889" }, { "Alex", "Sidorow", "45667" }, { "DNMO", "Alekseew", "9983377" } }; for (int i=0; i3; i++) of  [i].FirstName  <' '  [i].LastName  <' '  [i].phone  <' '; of.close(); int index=0; ifstream file("file"); while (!file.eof()){ file >> X[index].FirstName >> X[index].LastName >> X[index].phone; index++; } file.close(); for (int i=0; i3; i++){ cout  [i].FirstName  <' '  [i].LastName  <' '  [i].phone  <'\n'; } }

У Вас же в коде используется операция >> , она работает до первого пробела.

Вы сами себя запутали:

ЦитатаСообщение от _Sora_ Посмотреть сообщение

Но во время считывание, ни один из мне известных методов не считывает пробелы.

Т. е. или Вам пробелы действительно нужны (например, для чтения строки непосредственно с пробелами).

ЦитатаСообщение от _Sora_ Посмотреть сообщение

У меня есть файл, где через пробел указаны имя фамилия номер телефона

Вам пробелы не нужны в принципе, они нужны в файле для разделения, но никак не Вам.

Я думаю, что Вам пробелы не нужны.

Регистрация: 30.10.2017
Сообщений: 34

ЦитатаСообщение от daslex Посмотреть сообщение

Сильно напоминает необходимость использования массива структур и незнание о массиве структур.
Вот то, что Вы описываете - это массив структур, хранимый в файле.

Вы правы, простите. Я не знал, забыл о существовании структур массивов, спасибо. Это же насколько проще, но я уже сделал по своему, по этому ещё раз спасибо, мой вариант вот так:

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
#define _CRT_SECURE_NO_WARNINGS #include "stdafx.h" #include #include #include #include #include #include using namespace std; void FindName() { char Name[20]; printf("\n\n--\n"); printf(": \n"); fgetc(stdin); fgets(Name, 20, stdin); printf("\n------------------------\n"); printf(":\n"); fstream file; file.open("0.txt", ios::in); string s = "", s1; while (getline(file, s1)) s += s1; file.close(); char *all = new char[s.length()]; for (int i = 0; i  s.length(); i++) { all[i] = s[i]; } int k[15]; int m = 0; for (int i = 0; i  sizeof(all); i++) { if (all[i] == ' ') { k[m] = i; m++; } } char *c = new char[20]; int Fin; for (int i = 0; i  m; i + 3) { int l = 0; bool b = true; for (int j = k[i] + 1; j  k[i + 1]; j++) { c[l] = all[j]; l++; } for (int j = 0; j  l; j++) { if (c[j] != Name[j]) b = false; if (b == false) break; } if (b == true) { Fin = i; break; } } for (int i = Fin; i  Fin + 3; i++) { int l = 0; for (int j = k[i] + 1; j  k[i + 1]; j++) { c[l] = all[j]; l++; } } cout  <": "  [0]  ; cout  <": "  [1]  ; cout  <": "  [2]  ; cout  ; }

Чтение файла, как прочитать пробел?

Прочитать цифры через пробел
Здравствуйте. Возник один вопрос при решении небольшой задачки: Я уточнял по поводу задачи. В.

Прочитать файл в обратном порядке т.е. встать в конец файла и прочитать до начальной позиции
подскажите пожалуйста как можно прочитать файл в обратном порядке т.е. стать в конец файла и.

Как прочитать информацию из файла
Здравствуйте. Есть программа, которая вычисляет определитель матрицы, но у неё проблемы с.

Как считать информацию из файла, если в конце стоит пробел?
У меня при считывании из файла в массив, если в конце файла стоит пробел, то копируется ещё один.

Как считать пробелы в c из файла

Под "текстовой обработкой" (в противовес "вычислительным задачам") здесь понимается огромный класс задач обработки информации нечислового характера, например редактирование текста, форматирование документов, поиск и сортировка, базы данных, лексический и синтаксический анализ, печать на принтере, преобразование формата таблиц, и.т.п.

7.1.

Напишите программу, "угадывающую" слово из заранее заданного списка по первым нескольким буквам. Выдайте сообщение "неоднозначно", если есть несколько похожих слов. Усложните программу так, чтобы список слов считывался в программу при ее запуске из файла list.txt

7.2.

Напишите программу, которая удваивает пробелы в тексте с одиночными пробелами.

7.3.

Напишите программу, которая копирует ввод на вывод, заменяя каждую последовательность из идущих подряд нескольких пробелов и/или табуляций на один пробел. Схема ее решения сходна с решением следующей задачи.

7.4.

Напишите программу подсчета слов в файле. Слово определите как последовательность символов, не включающую символы пробела, табуляции или новой строки. "Канонический" вариант решения, приведенный у Кернигана и Ритчи, таков:

#include ctype.h> #include stdio.h> const int YES=1, NO=0; main()< register int inWord = NO; /* состояние */ int words = 0, c; while((c = getchar()) != EOF) if(isspace(c) || c == '\n') inWord = NO; else if(inWord == NO)< inWord = YES; ++words; > printf("%d слов\n", words); >

Обратите внимание на конструкцию const. Это объявление имен как констант. Эта конструкция близка к

#define YES 1

но позволяет компилятору

  • более строго проверять тип, т.к. это типизированная константа;
  • создавать более экономный код;
  • запрещает изменять это значение.
main()< /* cc 00.c -o 00 -lm */ double sqrt(double); const double sq12 = sqrt(12.0); #define SQRT2 sqrt(2.0) double x; x = sq12 * sq12 * SQRT2 * SQRT2; /* @1 */ sq12 = 3.4641; /* @2 */ printf("%g %g\n", sq12, x); >

Использование #define превратит строку @1 в

x = sq12 * sq12 * sqrt(2.0) * sqrt(2.0);

то есть создаст код с двумя вызовами функции sqrt. Конструкция же const заносит вычисленное выражение в ячейку памяти и далее просто использует ее значение. При этом компилятор не позволяет впоследствии изменять это значение, поэтому строка @2 ошибочна.

Теперь предложим еще одну программу подсчета слов, где слово определяется макросом isWord, перечисляющим буквы допустимые в слове. Программа основана на переключательной таблице функций (этот подход применим во многих случаях):

#include #include int wordLength, inWord, words; /* = 0 */ char aWord[128], *wrd; void space (c)<> void letter (c) < wordLength++; *wrd++ = c; >void begWord(c)< wordLength=0; inWord=1; wrd=aWord; words++; letter(c); > void endWord(c) < inWord=0; *wrd = '\0'; printf("Слово '%s' длины %d\n", aWord, wordLength); >void (*sw[2][2])() = < /* !isWord */ < space, endWord >, /* isWord */ < begWord, letter > /* !inWord inWord */ >; #define isWord(c) (isalnum(c) || c=='-' || c=='_') main()< register c; while((c = getchar()) != EOF) (*sw[isWord(c)][inWord])(c); printf("%d слов\n", words); >
7.5.

Напишите программу, выдающую гистограмму длин строк файла (т.е. таблицу: строк длины 0 столько-то, длины 1 - столько-то, и.т.п., причем таблицу можно изобразить графически).

7.6.

Напишите программу, которая считывает слово из файла in и записывает это слово в конец файла out.

7.7.

Напишите программу, которая будет печатать слова из файла ввода, причем по одному на строку.

7.8.

Напишите программу, печатающую гистограмму длин слов из файла ввода.

7.9.

Напишите программу, читающую слова из файла и размещающую их в виде двунаправленного списка слов, отсортированного по алфавиту. Указания: используйте динамическую память (malloc) и указатели; напишите функцию включения нового слова в список на нужное место.

В конце работы распечатайте список дважды: в прямом и в обратном порядке.

Усложнение: не хранить в списке дубликаты; вместо этого вместе со словом хранить счетчик количества его вхождений в текст.

7.10.

Напишите программу, которая печатает слова из своего файла ввода, расположенные в порядке убывания частоты их появления. Перед каждым словом напечатайте число частоты его появления.

7.11.

Напишите программу, читающую файл построчно и печатающую слова в каждой строке в обратном порядке.

7.12.

Напишите программу копирования ввода на вывод таким образом, чтобы из каждой группы последовательно одинаковых строк выводилась только одна строка. Это аналог программы uniq в системе UNIX. Ответ:

#include /* char *gets(); */ char buf1[4096], buf2[4096]; char *this = buf1, *prev = buf2; main() < long nline =0L; char *tmp; while( gets(this))< if(nline)< /* сравнить новую и предыдущую строки */ if( strcmp(this, prev)) /* различны ? */ puts(prev); >/* обмен буферов: */ tmp=prev; prev=this; this=tmp; nline++; /* номер строки */ >/* endwhile */ if( nline ) puts(prev); /* последняя строка всегда выдается */ >
7.13.

Составьте программу, которая будет удалять в конце (и в начале) каждой строки файла пробелы и табуляции, а также удалять строки, целиком состоящие из пробелов и табуляций.

7.14.

Для экономии места в файле, редакторы текстов при записи отредактированного файла сжимают подряд идущие пробелы в табуляцию. Часто это неудобно для программ обработки текстов (поскольку требует особой обработки табуляций - это ОДИН символ, который на экране и в тексте занимает НЕСКОЛЬКО позиций!), поэтому при чтении файла мы должны расширять табуляции в нужное количество пробелов, например так:

/* заменять табуляции на пробелы */ void untab(s) register char *s; < char newstr[256]; /* новая строка */ char *src = s; int n; /* счетчик */ register dstx; /* координата x в новой строке */ for(dstx = 0; *s != '\0'; s++) if( *s == '\t')< for(n = 8 - dstx % 8 ; n >0 ; n--) newstr[dstx++] = ' '; >else newstr[dstx++] = *s; newstr[dstx] = '\0'; strcpy(src, newstr); /* строку на старое место */ >
7.15.

Напишите обратную функцию, сжимающую подряд идущие пробелы в табуляции.

void tabify() < int chr; int icol, ocol; /* input/output columns */ for(icol = ocol = 0; ; )< if((chr = getchar()) == EOF) break; switch(chr)< case ' ': icol++; break; case '\n': case '\r': ocol = icol = 0; putchar(chr); break; case '\t': icol += 8; icol &= ~07; /* icol -= icol % 8; */ break; default: while(((ocol + 8) & ~07) while(ocol < icol)< putchar(' '); ocol++; >putchar(chr); icol++; ocol++; break; > > >
7.16.

Составьте программу, укорачивающую строки исходного файла до заданной величины и помещающую результат в указанный файл. Учтите, что табуляция разворачивается в несколько пробелов!

7.17.

Разработайте программу, укорачивающую строки входного файла до 60 символов. Однако теперь запрещается обрубать слова.

7.18.

Разработайте программу, заполняющую промежутки между словами строки дополнительными пробелами таким образом, чтобы длина строки была равна 60 символам.

7.19.

Напишите программу, переносящую слишком длинные строки. Слова разбивать нельзя (неумешающееся слово следует перенести целиком). Ширину строки считать равной 60.

7.20.

Составьте программу, центрирующую строки файла относительно середины экрана, т.е. добавляющую в начало строки такое количество пробелов, чтобы середина строки печаталась в 40-ой позиции (считаем, что обычный экран имеет ширину 80 символов).

7.21.

Напишите программу, отсекающую n пробелов в начале каждой строки (или n первых любых символов). Учтите, что в файле могут быть строки короче n (например пустые строки).

#include /* . текст функции untab(); . */ void process(char name[], int n, int spacesOnly)< char line[256]; int length, shift, nline = 0; char newname[128]; FILE *fpin, *fpout; if((fpin = fopen(name, "r")) == NULL)< fprintf(stderr, "Не могу читать %s\n", name); return; > sprintf(newname, "_%s", name); /* например */ if((fpout = fopen(newname, "w")) == NULL)< fprintf(stderr, "Не могу создать %s\n", newname); fclose(fpin); return; > while(fgets(line, sizeof line, fpin))< ++nline; if((length = strlen(line)) && line[length-1] == '\n') line[--length] = '\0'; /* обрубить '\n' */ untab(line); /* развернуть табуляции */ for(shift=0; line[shift] != '\0' && shift < n ; ++shift) if(spacesOnly && line[shift] != ' ') break; if(*line && shift != n ) /* Предупреждение */ fprintf(stderr, "Начало строки #%d слишком коротко\n", nline); fprintf(fpout, "%s\n", line+shift); /* нельзя было fputs(line+n, fpout); * т.к. эта позиция может быть ЗА концом строки */ > fclose(fpin); fclose(fpout); > void main(int argc, char **argv)< if( argc != 3 ) exit(1); process(argv[2], atoi(argv[1]) /* 8 */, 1); exit(0); >
7.22.

Напишите программу, разбивающую файл на два по вертикали: в первый файл попадает левая половина исходного файла, во второй - правая. Ширину колонки задавайте из аргументов main(). Если же аргумент не указан - 40 позиций.

7.23.

Напишите программу сортировки строк в алфавитном порядке. Учтите, что функция strcmp() сравнивает строки в порядке кодировки, принятой на данной конкретной машине. Русские буквы, как правило, идут не в алфавитном порядке! Следует написать функцию для алфавитного сравнения отдельных символов и, пользуясь ею, переписать функцию strcmp().

7.24.

Отсортируйте массив строк по лексикографическому убыванию, игнорируя различия между строчными и прописными буквами.

7.25.

Составьте программу дихотомического поиска в отсортированном массиве строк (методом деления пополам).

/* Поиск в таблице методом половинного деления: dihotomia */ #include struct elem < char *name; /* ключ поиска */ int value; >table[] = < /* имена строго по алфавиту */ < "andrew", 17 >, < "bill", 23 >, < "george", 55 >, < "jack", 54 >, < "jaw", 43 >, < "john", 33 >, < "mike", 99 >, < "paul", 21 >, < "sue", 66 >, /* SIZE - 2 */ < NULL, -1 >, /* SIZE - 1 */ /* NULL введен только для распечатки таблицы */ >; #define SIZE (sizeof(table) / sizeof(struct elem)) /* Дихотомический поиск по таблице */ struct elem *find(s, table, size) char *s; /* что найти ? */ struct elem table[]; /* в чем ? */ int size; /* среди первых size элементов */ < register top, bottom, middle; register code; top = 0; /* начало */ bottom = size - 1; /* конец: индекс строки "sue" */ while( top 0 )< top = middle + 1; >else if( code < 0 )< bottom = middle - 1; >else return &table[ middle ]; > return (struct elem *) NULL; /* не нашел */ > /* распечатка таблицы */ void printtable(tbl) register struct elem *tbl; < for( ; tbl->name != NULL ; tbl++ )< printf( "%-15s %d\n", tbl->name, tbl->value ); > > int main() < char buf[80]; struct elem *ptr; printtable(table); for(;;)< printf( "->" ); if( gets( buf ) == NULL) break; /* EOF */ if( ! strcmp( buf, "q" )) exit(0); /* quit: выход */ ptr = find( buf, table, SIZE-1 ); if( ptr ) printf( "%d\n", ptr->value ); else < printf( "--- Не найдено ---\n" ); printtable(table); >> return 0; >
7.26.

Напишем функцию, которая преобразует строку так, что при ее печати буквы в ней будут подчеркнуты, а цифры - выделены жирно. Формат текста с выделениями, который создается этим примером, является общепринятым в UNIX и распознается некоторыми программами: например, программа просмотра файлов less (more) выделяет такие буквы на экране специальными шрифтами или инверсией фона.

#define LEN 9 /* потом напишите 256 */ char input[] = "(xxx+yyy)/123.75=?"; char output[LEN]; void main( void )< int len=LEN, i; void bi_conv(); char c; bi_conv(input, output, &len); if(len > LEN) < printf("Увеличь LEN до %d\n", len); len = LEN; /* доступный максимум */ >for(i=0; i < len && (c = output[i]); ++i) putchar(c); putchar('\n'); >/* Заметьте, что include-файлы не обязательно * должны включаться в самом начале программы! */ #include #include #define PUT(c) < count++; \ if(put < *len)< *p++ = (c); ++put;>> #define GET() (*s ? *s++ : EOF) void bi_conv( /*IN*/ char *s, /*OUT*/ char *p, /*INOUT*/ int *len ) < int count, put, c; for(count=put=0; (c=GET()) != EOF; )< /* жирный: C\bC */ /* подчеркнутый: _\bC */ if(isalpha(c))< PUT('_'); PUT('\b'); >else if(isdigit(c)) < PUT( c ); PUT('\b'); >PUT(c); > PUT('\0'); /* закрыть строку */ *len = count; #undef PUT #undef GET >

Напишите программу для подобной обработки файла. Заметим, что для этого не нужны промежуточные строки input и output и построчное чтение файла; все, что надо сделать, это определить

#define PUT(c) if(c)putchar(c) #define GET() getchar()

Напишите подобную функцию, удваивающую буквы в ссттррооккее.

7.27.

Напишите программу, удаляющую из файла выделения. Для этого надо просто удалять последовательности вида C\b

#include stdio.h> #define NOPUT (-1) /* не символ ASCII */ /* Названия шрифтов - в перечислимом типе */ typedef enum < NORMAL=1, ITALICS, BOLD, RED=BOLD >font; int ontty; font textfont; /* текущее выделение */ #define setfont(f) textfont=(f) #define getfont() (textfont) #define SetTtyFont(f) if(ontty) tfont(f) /* Установить выделение на экране терминала */ void tfont(font f)< /* только для ANSI терминала */ static font ttyfont = NORMAL; if(ttyfont == f) return; printf("\033[0m"); /* set NORMAL font */ switch(ttyfont = f)< case NORMAL: /* уже сделано выше */ break; case BOLD: printf("\033[1m"); break; case ITALICS: /* use reverse video */ printf("\033[7m"); break; > > void put(int c)< /* Вывод символа текущим цветом */ if(c == NOPUT) return; /* '\b' */ SetTtyFont(getfont()); putchar(c); setfont(NORMAL); /* Ожидать новой C\b посл-ти */ > void main()< register int c, cprev = NOPUT; /* Стандартный вывод - это терминал ? */ ontty = isatty(fileno(stdout)); setfont(NORMAL); while((c = getchar()) != EOF)< if(c == '\b')< /* выделение */ if((c = getchar()) == EOF) break; if(c == cprev) setfont(BOLD); else if(cprev == '_') setfont(ITALICS); else /* наложение A\bB */ setfont(RED); > else put(cprev); cprev = c; > put(cprev); /* последняя буква файла */ SetTtyFont(NORMAL); >
7.28.

Напишите программу печати на принтере листинга Си-программ. Ключевые слова языка выделяйте двойной надпечаткой. Для выдачи на терминал напишите программу, подчеркивающую ключевые слова (подчеркивание - в следующей строке). Упрощение: выделяйте не ключевые слова, а большие буквы. Указание: для двойной печати используйте управляющий символ '\r' - возврат к началу той же строки; затем строка печатается повторно, при этом символы, которые не должны печататься жирно, следует заменить на пробелы (или на табуляцию, если этот символ сам есть '\t').

© Copyright А. Богатырев, 1992-95
Си в UNIX

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *