Выбрать все строки из файла, содержащие искомую подстроку, и вывести их на стандартный вывод задом наперед - C (СИ)
Формулировка задачи:
Здравствуйте. Мне нужно было сделать программу-поисковик по файлу. Задача была следующая. Есть текстовый файл неопределенной длины. Пользователь задает искомую подстроку. Нужно выбрать все строки из файла, содержащие искомую подстроку, и вывести их на стандартный вывод задом на перед. При этом искомая подстрока задается как аргумент командной строки(argv). В си я программирую не очень долго, так что косячница я знатная. Пожалуйста, помогите найти ошибку в моей программе. То, что закомментировано - моя попытка заставить программу работать при вводе подстроки в самой программе.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define CHUNK_SIZE 1 typedef struct tagSp { char *s; struct tagSp *next; } sp; int grow(char **buf, int new_size) { if (new_size % CHUNK_SIZE == 0) { *buf = realloc(*buf, new_size); if (*buf == NULL) return 1; } return 0; } void print_reverse(char *line) { int i,n; char c; for(i=0;line[i]!='\n' && line[i]!=EOF;i++); for(n=i;n>=0;n--) { printf("%c",line[n]); } printf("\n"); } void find_and_print(char **lines,char *s,int lines_pos) { int i; for(i=0;i<lines_pos;i++){ if (strstr(lines[i],s)!=NULL) print_reverse(lines[i]); } } int main(int argc, char **argv) { FILE *f; char *buf,c,*s; char **lines; size_t buf_size,buf_pos; int err,i; if(argc!=2) { printf("Вы забыли ввести искомую строку.\n"); exit(1); } f = fopen("c:\\1.txt","r+"); if (f == NULL) { printf("error: can't open file\n"); return 1; } lines=(char**)malloc(sizeof(char*)); int size_lines=sizeof(char*),lines_pos=0; for(i=0;c!=EOF;i++){ buf_size = CHUNK_SIZE; buf_pos = 0; buf = malloc(CHUNK_SIZE); while((c = fgetc(f)) != EOF && c!='\n') { err = grow(&buf,++buf_size); if (err == 1) return 1; buf[buf_pos++] = c; } buf[++buf_pos] = 10; grow(lines,size_lines+sizeof(char*)); lines_pos++; lines[i]=buf; printf("%s\n",lines[i]); } /*buf = malloc(CHUNK_SIZE); buf_pos=0; while((c = fgetc(stdin)) != EOF && c!='\n') { err = grow(&buf,++buf_size); if (err == 1) return 1; buf[buf_pos++] = c; }*/ printf("%s\n",buf); printf("%s\n",argv[1]); buf=argv[1]; find_and_print(lines,buf,lines_pos); for(i=0;i<lines_pos;i++) free(lines[i]); free(lines); return 0; }
Решение задачи: «Выбрать все строки из файла, содержащие искомую подстроку, и вывести их на стандартный вывод задом наперед»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #include <string.h> char *revStr(char *str){ char *h, *t, c; for ( h = str, t = str + strlen(str) - 1; h < t; h++, t-- ){ c = *h; *h = *t; *t = c; } return str; } /* Есть текстовый файл неопределенной длины. Пользователь задает искомую подстроку. Нужно выбрать все строки из файла, содержащие искомую подстроку, и вывести их на стандартный вывод задом на перед. При этом искомая подстрока задается как аргумент командной строки(argv). */ /* первый аргумент - имя файла, второй - что ищем (если из нескольких слов, то в кавычках) */ int main(int argc, char **argv){ FILE *f; char buf[BUFSIZ], *p, **strings; long count, i; if ( argc < 3 ){ printf("Usage: %s <file_name> <string_to_find>\n", *argv); exit(1); } if ( ( f = fopen(argv[1], "rb") ) == NULL ){ fprintf(stderr, "%s: can't open file %s for input!\n", argv[0], argv[1]); exit(1); } strings = NULL; count = 0; while ( fgets(buf, sizeof(buf), f) ){ if ( p = strrchr(buf, '\n') ) *p = 0; if ( strstr(buf, argv[2]) ){ if ( ( strings = (char**)realloc(strings, sizeof(char*) * (count + 1)) ) == NULL ){ fprintf(stderr, "%s: memory error!\n", *argv); exit(1); } if ( ( strings[count] = strdup(buf) ) == NULL ){ fprintf(stderr, "%s: memory error!\n", *argv); exit(1); } ++count; } } if ( ferror(f) ){ fprintf(stderr, "%s: error while reading file %s\n", argv[0], argv[1]); exit(1); } fclose(f); if ( !strings || !count ){ fprintf(stderr, "%s: no strings containing \"%s\" found in file %s\n", argv[0], argv[2], argv[1]); exit(1); } for ( i = count - 1; i >= 0; --i ) printf("%s\n", revStr(strings[i])); for ( i = 0; i < count; ++i ) free(strings[i]); free(strings); exit(0); }
Объяснение кода листинга программы
- Первый аргумент функции main() - имя файла, второй аргумент - искомая подстрока.
- Создается массив символов 'buf' для чтения файла построчно.
- Если аргументов командной строки меньше 3, выводится сообщение об ошибке и программа завершается.
- Открывается файл для чтения.
- В случае ошибки при открытии файла выводится сообщение об ошибке и программа завершается.
- Строки из файла сохраняются в массиве строк 'strings'.
- Если произошла ошибка при выделении памяти для массива строк или при выделении памяти для каждой строки, выводится сообщение об ошибке и программа завершается.
- Последняя строка в каждой строке удаляется (заменит символ новой строки на 0).
- Если строка содержит искомую подстроку, она добавляется в массив строк.
- Если при чтении файла произошла ошибка, выводится сообщение об ошибке и программа завершается.
- Файл закрывается.
- Если массив строк пуст или не содержит ни одной строки с искомой подстрокой, выводится сообщение об ошибке и программа завершается.
- Все строки из массива строк выводятся в обратном порядке.
- Все строки из массива строк освобождаются.
- Массив строк освобождается.
- Программа завершается.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д