Выбрать все строки из файла, содержащие искомую подстроку, и вывести их на стандартный вывод задом наперед - 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);
}

Объяснение кода листинга программы

  1. Первый аргумент функции main() - имя файла, второй аргумент - искомая подстрока.
  2. Создается массив символов 'buf' для чтения файла построчно.
  3. Если аргументов командной строки меньше 3, выводится сообщение об ошибке и программа завершается.
  4. Открывается файл для чтения.
  5. В случае ошибки при открытии файла выводится сообщение об ошибке и программа завершается.
  6. Строки из файла сохраняются в массиве строк 'strings'.
  7. Если произошла ошибка при выделении памяти для массива строк или при выделении памяти для каждой строки, выводится сообщение об ошибке и программа завершается.
  8. Последняя строка в каждой строке удаляется (заменит символ новой строки на 0).
  9. Если строка содержит искомую подстроку, она добавляется в массив строк.
  10. Если при чтении файла произошла ошибка, выводится сообщение об ошибке и программа завершается.
  11. Файл закрывается.
  12. Если массив строк пуст или не содержит ни одной строки с искомой подстрокой, выводится сообщение об ошибке и программа завершается.
  13. Все строки из массива строк выводятся в обратном порядке.
  14. Все строки из массива строк освобождаются.
  15. Массив строк освобождается.
  16. Программа завершается.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.4 из 5
Похожие ответы