Как считать пробелы в c из файла
Здравствуйте.
Имеется следующее задание:
Написать функцию, которая читает данные о ноутбуках из файла note.txt (см. после варианта 20) в структуру приведенного вида. Написать функцию, которая записывает содержимое структуры в конец бинарного файла. Структура бинарного файла: первые два байта (целое) — число записей в файле; далее записи в формате структуры NOTEBOOK.
Написать программу, в которой на основе разработанных функций осуществляется чтение данных только для тех ноутбуков, объем HDD которых меньше 1 Гбайт, и запись считанных данных в бинарный файл в алфавитном порядке по наименованию.
Стандартный scanf считывает до пробела, в моем же случае типы данных в файле разделены пробелами.
Также интересует то, как быть с теми данными, которые в структуру записывать не нужно. Считывать в переменные?
Заранее спасибо за помощь.
Пользователь
Регистрация: 05.09.2012
Сообщений: 56
есть такая функция как gets()
она считывает строку в какой то массив символом а потос с этим массивом символов ты можешь работать
ну например маленький пример
int str[100];
while(!feof(имя_файла))
gets(имя_файла(с которого считываешь строки),100(колличество считываемых символов),str(куда считываем)) //gets(f,100,str);
ну а потом делаешь все необходимое с массивом символов. В нашей ситуации действия будут происходить пока не будет достигнут конец файла.
>
ну как то так
| Похожие темы | ||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| как считать каждую строку в файле? | proef | Помощь студентам | 10 | 08.06.2013 18:24 |
| FASM. Считать содержимое файла в строку и затем записать обратно в файл | Zart | Помощь студентам | 0 | 19.04.2011 17:02 |
| считать строку из файла | Farrel | Общие вопросы C/C++ | 1 | 09.12.2010 01:47 |
| Как считать последнюю строку ? | Katmai | Общие вопросы Delphi | 13 | 27.07.2010 20:49 |
| Считать определенную строку из файла | DimkinStd | Работа с сетью в Delphi | 4 | 15.02.2007 22:30 |
Чтение из файла string с пробелом
не хочется соединять две стринги. Может есть какой-нибудь вариант работы не через пробелы, а через табы?
23 фев 2018 в 18:21
Так, судя по тому, что ответ не нравится. Что именно вам нужно? Поясните понятнее, чего вы хотите добиться.
23 фев 2018 в 18:30
Значит считываю с файла пример, это все поля класса Car, когда оно считывает CD 5678-4 (номер машины) бьет на две строки. Вопрос в том можно ли без склеивания двух строк CD и 5678-4 обойтись
23 фев 2018 в 18:36
А если там будет три слова? 🙂 Разделяйте поля чем-то при вводе — чем угодно — и используйте getline с разделителем (см. ответ). См. также ru.wikipedia.org/wiki/CSV
23 фев 2018 в 18:38
так именно поэтому перегружены >> чтобы сразу инициализировать поля
23 фев 2018 в 18:40
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
char buf[SIZE]; stream.getline(buf,SIZE);
string s; getline(stream,s);
Можно с нестандартным разделителем —
getline(stream,s,'\t');
Отслеживать
ответ дан 23 фев 2018 в 18:14
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков
Спасибо. Это искал
23 фев 2018 в 18:47
- c++
- строки
- fstream
-
Важное на Мете
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2024 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2024.1.3.2953
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Функции-члены входного потока
Функции — члены потока ввода используются для дисковых операций ввода.
open
Если вы используете входной поток файлов ( ifstream ), необходимо связать этот поток с определенным файлом диска. Это можно сделать в конструкторе или использовать функцию open . В любом случае аргументы одни и те же.
Обычно при открытии файла, связанного с входным потоком ios_base::openmode (используется ios::in режим по умолчанию). openmode Список флагов см. в разделе ios_base::openmode . Флаги можно объединить с побитовой «или» ( | ) оператором.
Чтобы прочитать файл, сначала используйте fail функцию-член, чтобы определить, существует ли она:
istream ifile("FILENAME"); if (ifile.fail()) // The file does not exist .
get
Неформатированная get функция-член работает как >> оператор с двумя исключениями. Во-первых, get функция включает символы пробела, а средство извлечения исключает пробелы при skipws установке флага (по умолчанию). Во-вторых, функция, скорее всего, get приведет к очистке связанного выходного потока ( cout например).
Вариант функции задает адрес буфера get и максимальное число символов для чтения. Это полезно для ограничения количества символов, отправленных в конкретную переменную, как показано в примере:
// ioo_get_function.cpp // compile with: /EHsc // Type up to 24 characters and a terminating character. // Any remaining characters can be extracted later. #include using namespace std; int main() < char line[25]; cout "; cin.get( line, 25 ); cout
Входные данные
1234
Образец вывода
1234
getline
Функция-член getline похожа на функцию get . Обе функции допускают третий аргумент, который указывает завершающий символ для входных данных. Значение по умолчанию — символ новой строки. Обе функции резервируют один символ для необходимого завершающего символа. Тем не менее, get оставляет конечный символ в потоке и getline удаляет конечный символ.
В следующем примере задается завершающий символ для потока ввода:
// getline_func.cpp // compile with: /EHsc #include using namespace std; int main( )
Входные данные
test
read
Функция-член read считывает байты из файла в указанную область памяти. Аргумент length определяет количество прочтенных байтов. Если этот аргумент не включен, чтение останавливается при достижении физического конца файла или в случае файла в текстовом режиме при чтении внедренного EOF символа.
Этот пример считывает двоичную запись из файла заработной платы в структуру:
#include #include using namespace std; int main() < struct < double salary; char name[23]; >employee; ifstream is( "payroll" ); if( is ) < // ios::operator void*() is.read( (char *) &employee, sizeof( employee ) ); cout else < cout >
Программа предполагает, что записи данных форматируются точно так же, как указано структурой без конца возвращаемых возвращаемых каретки или символов канала строки.
seekg и tellg
Потоки входного файла хранят внутренний указатель на позицию в файле, с которой будет продолжаться чтение. Этот указатель можно установить функцией seekg , как показано ниже:
#include #include using namespace std; int main( ) < char ch; ifstream tfile( "payroll" ); if( tfile ) < tfile.seekg( 8 ); // Seek 8 bytes in (past salary) while ( tfile.good() ) < // EOF or failure stops the reading tfile.get( ch ); if( !ch ) break; // quit on null cout > else < cout >
seekg Чтобы использовать для реализации систем управления данными, ориентированных на запись, умножьте размер записи фиксированной длины на номер записи, чтобы получить положение байтов относительно конца файла, а затем используйте get объект для чтения записи.
Функция-член tellg возвращает текущую позицию в файле для чтения. Это значение имеет тип streampos , определенный typedef в . В следующем примере выполняется чтение файла и показ сообщения с позициями пробелов.
#include #include using namespace std; int main( ) < char ch; ifstream tfile( "payroll" ); if( tfile ) < while ( tfile.good( ) ) < streampos here = tfile.tellg(); tfile.get( ch ); if ( ch == ' ' ) cout > else < cout >
close
Функция-член close закрывает файл диска, связанный с входным потоком файлов, и освобождает дескриптор файла операционной системы. Деструктор ifstream закрывает файл, но можно использовать close функцию, если нужно открыть другой файл для одного объекта потока.
Как считать пробелы в 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