Простое чтение строки произвольного (любого) размера из консоли в языке си (C , С)
Primary tabs
Forums:
Читать будем блоками из стандартного потока ввода, оригинал здесь = http://www.cplusplus.com/forum/beginner/... ,
а русские комментарии к коду, собственно, на этой вот странице.
- Log in to post comments
- 25605 reads
vedro-compota
Fri, 09/30/2011 - 15:04
Permalink
собственно, код следующий
собственно, код следующий ,но со смыслом пока туго. =
/* функция ниже считывает строчку переменной длинны и возвращает указатель на область памяти, занимаемую считанной строкой.*/ char* simple_readline( const char* prompt, unsigned block_size ) { char* result; /* The malloc()ed string to return = "ответ" нашей функции вызывающему её блоку */ char* block; /* Each chunk of the string = очердной кусок читаемой строки */ char* ok; /* Used to check for input errors = идентификатор ошибки , которая может возникнуть при чтении.*/ unsigned size; /* The current size of the entire string , размерность читаемого блока данных (читать будем из стандартного потока ввода.) */ unsigned n; /* strlen() of the last block = длинна (в символах) последнего прочитанного блока - беззнаковый тип */ if (!block_size) block_size = 50; /* */ if (prompt) printf( "%s", prompt ); block = result = (char*)malloc( size = block_size ); /* выделям память размера block_size и одновременно размер размер возвращаемой строки также получает значение блок - сайз.*/ if (!result) return NULL; /* если предыдущая операция завершилась неудачей , то завершаем эту функцию (чтения строки) и передаём наверх НАЛЛ*/ *result = '\0'; /* инициализируем область памяти */ for (;;) { /* Get the next block of characters until EOL = читаем следующий (если не первый - то следующий) блок символов до тех пор пока не встретиться символ конца строки*/ ok = fgets( block, block_size, stdin ); if (!ok) break; /* If we found EOL we are done если вдруг последний символ очередного прочитанного блока - это конец строки, то выходим из цикла командой break; */ n = strlen( block ); if (block[ n -1 ] == '\n') break; /* Else add more memory and try again = если же мы ещё не достигли конца читаемой из консоли строки то выделяем доболнительную память , чтобы разместить новые считанные блоки */ ok = (char*)realloc( result, size += block_size ); if (!ok) break; result = ok; } if (!(*result)) { free( result ); result = NULL; } return result; }_____________
матфак вгу и остальная классика =)
vedro-compota
Fri, 09/30/2011 - 16:25
Permalink
описания функций , использованных в данном примере
Описание этой функции и последующих взяты с сайта = http://www.codenet.ru/progr/cpp/sprd/fge... (если в этой теме буду использовать другой источник - обязательно дам ссылку)
fgets() -чтение строки из потока (например - стандартного потока ввода stdin или какого-либо файла)
Описание
Считывает литеры из потока fp в строку по указателю
str. Чтение заканчивается, когда встречается литера
`\n' (новая строка), конец файла, возникает ошибка чте-
ния или число прочитанных литер достигает n-1. Строка
завершается 0. Литера '\n' (новая строка) включается в
строку (перед 0).
Использование
#include <stdio.h> char *fgets(char *str, int n, FILE *fp); /* ANSI */Возвращаемое значение
Возвращает строку str в случае успеха. Если не было
прочитано ни одной литеры и произошла ошибка чтения
или встречен EOF, возвращает NULL, а строка str оста-
ется без изменения. Если возникла ошибка при чтении,
возвращает NULL, а в строке возможен мусор.
Пример
#include <stdio.h> main() { char buffer[225]; int buflen; char *result; buflen=255; fputs("Введите строку данных\n", stdout); result=fgets(buffer, buflen, stdin); if (!result) printf("\n конец файла (EOF) или ошибка (ERROR)\n"); else fputs(buffer, stdout); }Рекомендация
Смотрите также fputs, gets, puts.
----------------------
когда fgets читатет строку, то - получившаяся строка завершается нулевым символом '\0'.
_____________
матфак вгу и остальная классика =)
vedro-compota
Fri, 09/30/2011 - 15:18
Permalink
realloc() - переразмещаем блок памяти, возможно изменяя размер
realloc - переразместить блок памяти
Описание
realloc изменяет размер ранее выделенного блока памя-
ти, на который указывает ptr. Размер этого блока после
обращения к realloc определяется параметром size. Если
size равен 0, блок освобождается и возвращается NULL.
Если ptr равен NULL, то отводится (по malloc) size
байтов памяти и возвращается указатель на этот массив
памяти. Если для расширения текущего блока места не
хватает, будет размещен новый блок, а текущий блок ос-
вободится. Текущие данные перепишутся в новый блок.
Использование
#include <stdlib.h> void *realloc(void *ptr, unsigned size); /* ANSI */Возвращаемое значение
Возвращается указатель на переразмещенный блок памя-
ти. Если нет подходящей памяти для выполнения realloc,
возвращается NULL (но память по ptr не освобождается).
Пример
#include <stdio.h> #include <stdlib.h> #include <string.h> main() { char *ptr; ptr = realloc(NULL, 20*sizeof(char)); strcpy(ptr, "Это первая часть, "); ptr = realloc(ptr, 100*sizeof(char)); strcat(ptr, "Это вторая часть); printf("%s\n", ptr); realloc(ptr, 0); }Рекомендация
Смотрите также calloc, free, malloc.
_____________
матфак вгу и остальная классика =)
vedro-compota
Fri, 09/30/2011 - 15:20
Permalink
malloc ()- выделение памяти по заданному адресу
malloc ()- выделение памяти по заданному адресу
Описание
Размещает блок памяти объемом numbytes байтов. Если
numbytes равен 0, то возвращает NULL.
Использование
#include <stdlib.h> void *malloc(unsigned numbytes); /* ANSI */Возвращаемое значение
Возвращает указатель на размещенный блок памяти. Либо
возвращает NULL при недостатке памяти или в случае
numbytes==0.
Пример
#include <stdlib.h> #include <stdio.h> #define NUM_INTS 7623 int *memblock; main() { memblock = malloc(NUM_INTS*sizeof(int)); if (memblock==NULL) printf("Нехватка памяти\n"); else printf("Память отведена\n"); free(memblock); }Рекомендация
Смотрите также calloc, free, realloc, farmalloc.
_____________
матфак вгу и остальная классика =)
vedro-compota
Fri, 09/30/2011 - 15:23
Permalink
free - освобождение памяти
free - освободить память
Описание
Освобождает память по указателю p. Эта память должна
быть выделена ранее с использованием функций calloc,
malloc или realloc. Если p = NULL, free бездействует.
Если был использован флаг компилятора строгой ANSI со-
вместимости, то free возвращает void (т. е. не возвра-
щает значения).
Предостережение: не освобождайте данные более одного раза,
не работайте с освобожденными данными.
Использование
#include <stdlib.h> int free(void *p); /* ANSI */Возвращаемое значение
Возвращает 0 в случае успеха или -1, если испорчен
механизм управления памятью или p ошибочно. Значе-
ние -1 указывает на наличие серьезной ошибки в прог-
рамме. free игнорирует несуразные указатели.
Пример
#include <stdio.h> #include <stdlib.h> main() { char * p: if ((p = malloc(1000))==NULL) printf("Не могу отвести память\n"); if (free(p) == -1) abort(); /* Что-то ужасно плохо */ }Рекомендация
Смотрите также calloc, malloc, realloc.
_____________
матфак вгу и остальная классика =)
vedro-compota
Thu, 10/20/2011 - 15:59
Permalink
но приведённый выше код
но приведённый выше код оказывается неправильным и не сработает , если размер блока окажется меньше, ем длина читаемой строки, подробнее ,причина в том, что при каждой итерациях, с номером >1 мы будем затирать строку result командой =
так как начала областей памяти, на которые указывают result и block могут совпадать.
Подробнее читайте здесь = http://www.daniweb.com/software-developm...
мы же теперь рассмотрим исправленный пример (источник = http://www.daniweb.com/software-developm...)
_____________
матфак вгу и остальная классика =)
vedro-compota
Thu, 10/06/2011 - 21:42
Permalink
вот оно - без всяких системных констант
чтение строки любого (произвольного) размера в си (размер блока определён заранее - но вы всегда можете переписать эту функцию - добавив в список параметров размерность читаемого "куска") =
char *simple_readline(void) { const size_t block_size = 5; /*определяем размер блока единовременно считываемых данных*/ char *result, *block, *temp; /* переменная-результат, переменная для очередного считанного блока и вспомогательная переменная*/ size_t size = block_size; /* присваиваем значение*/ size_t n = 0; /* ещё одна вспомогательная переменная - в дальнейшем послужит для определения значения последнего элемента строки (будем проверять - символ ли переноса это на новую строку)*/ result = block = (char*)malloc(size); /* выделям область памяти размером с единовременно читаемый блок данных и переводим два указателя на эту область - в том числе и указатель на строку-результат*/ if (!result) return NULL; *result = '\0'; for (;;) { if (fgets(block, block_size, stdin) == NULL) break; n += strlen(block); if (result[n - 1] == '\n') break; size += block_size; temp = (char*)realloc(result, size); if (temp == NULL) break; result = temp; block = result + n; } if (result[0] == '\0') { free(result); result = NULL; } return result; }_____________
матфак вгу и остальная классика =)
tata_la
Thu, 12/01/2011 - 16:18
Permalink
ну-ну) ещё бы поменьше
ну-ну) ещё бы поменьше лишнего)
_________ _ _ ______
dthcbz фкн вгу and co