Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 01.12.2018
Сообщений: 6

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

01.12.2018, 00:38. Показов 1512. Ответов 11

Студворк — интернет-сервис помощи студентам
Здравствуйте, мне необходимо считывать из файла строки (строками считаются все символы до '\n') с помощью специальной функции, а потом работать с каждой строкой через цикл. Проще показать код который у меня есть: он выводит последний результат моей статической переменной.

C
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
84
#include "get_next_line.h"
#include <stdio.h>
 
void    *ft_memalloc(size_t size) // Просто безопасное выделение памяти
{
    void    *mem;
 
    mem = malloc(size);
    if (!mem)
        return (NULL);
    return (ft_memset(mem, 0, size));  // memset можно использовать из стандарта
}
 
char    *ft_strnew(size_t size) // Выделяем память под строку
{
    return ((char*)ft_memalloc(sizeof(char) * (size + 1)));
}
 
char    *ft_strsub(char const *s, unsigned int start, size_t len) // Копируем нужную часть из получаемого буфера
{
    size_t  i;
    char    *str;
 
    i = 0;
    if (!s)
        return (NULL);
    str = ft_strnew(len);
    if (!str)
        return (NULL);
    while (i < len && s[start])
    {
        str[i] = s[start];
        i++;
        start++;
    }
    str[i] = '\0';
    return (str);
}
 
int get_next_line(int fd, char **line) // Сама функция, может возвращать 0(чтение завершено), 1(идет чтение) или -1(ошибка)
{
    static char buffer[1024];
    char        c;
    int         index;
    int         ret;
 
    index = 0;
    while ((ret = read(fd, &c, BUFF_SIZE))) // BUFF_SIZE = 1
    {
        if (c != '\n')
            buffer[index++] = c;
        else
        {
            *line = ft_strsub(buffer, 0, index);
            buffer[index] = '\0';
            index = 0;
            printf("%s\n", buffer);
        }
    }
    return (1);
}
 
int main(int argc, char **argv)
{
    int i;
    int fd;
    char    *line;
 
    if (argc == 2)
    {
        i = 0;
        fd = open(argv[1], O_RDONLY);
        get_next_line(fd, &line); // Пока работает только так
        ft_putstr(line);
        ft_putchar('\n');
        // while ((get_next_line(fd, &line)) == 1) нужно чтобы работало с этим циклом
        // {
        //  ft_putstr(line); // Можно заменить на printf("%s", line)
        //  ft_putchar('\n');
        // }                         Пока что зацикливается...
        close(fd);
    }
    return (0);
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.12.2018, 00:38
Ответы с готовыми решениями:

Считывание строк из файла и работа с ними
Мне нужно пройтись по файлу до его конца и считать строки. С каждой строкой надо будет потом поработать. Как считать файл по строчно? Я...

Чтение строк с файла и работа с ними
Есть файл. В нём строки. Требуется проверить существует ли файл. Сделал такой блок string FilesLines; try {...

Как производить считывание данных из uitable и работа с ними?
Есть функции и форма с таблицами в которые надо вносить данные , отработать на них и вывести в другие таблицы, как это производить?

11
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
01.12.2018, 11:38
48: while (ret) переделать в while (ret > 0)
после 57 вставить break;
60: return (ret);
Заодно подумать, что делать если c == '\0' или index == sizeof(buffer);
0
0 / 0 / 0
Регистрация: 01.12.2018
Сообщений: 6
01.12.2018, 11:48  [ТС]
Цитата Сообщение от prik Посмотреть сообщение
48: while (ret) переделать в while (ret > 0)
после 57 вставить break;
60: return (ret);
Заодно подумать, что делать если c == '\0' или index == sizeof(buffer);
Спасибо, а почему мой while не подходит?
Также хотелось бы узнать, будет ли данный код работать с любыми файлами, просто у меня буфер на 1024 элемента, а если файл будет больше?
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
01.12.2018, 11:58
Цитата Сообщение от ramory-l Посмотреть сообщение
Спасибо, а почему мой while не подходит?
У вас написано: повторять до тех пор пока файл не кончился.
Нужно повторять пока файл не кончился и нет ошибки чтения.
Цитата Сообщение от ramory-l Посмотреть сообщение
Также хотелось бы узнать, будет ли данный код работать с любыми файлами, просто у меня буфер на 1024 элемента, а если файл будет больше
Нет.
Цитата Сообщение от prik Посмотреть сообщение
Заодно подумать, что делать если c == '\0' или index == sizeof(buffer);
0
0 / 0 / 0
Регистрация: 01.12.2018
Сообщений: 6
01.12.2018, 12:08  [ТС]
Цитата Сообщение от prik Посмотреть сообщение
Заодно подумать, что делать если c == '\0' или index == sizeof(buffer);
Это если файл не закончился, но где-то в середине есть '\0'? Честно говоря, не совсем понимаю для чего эти проверки, объясните пожалуйста, у меня просто и без них все работает.
0
 Аватар для weterok
36 / 28 / 9
Регистрация: 11.11.2018
Сообщений: 163
01.12.2018, 15:50
если где- то в середине есть '\0' то это считается конец строки, потому что это конечный символ строки и в середине его быть не должно.
0
0 / 0 / 0
Регистрация: 01.12.2018
Сообщений: 6
04.12.2018, 19:26  [ТС]
Решил по-другому:
C
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
int ft_cut_line(int fd, char **line, char **array)
{
    int     i;
    char    *temp;
 
    i = 0;
    while (array[fd][i] != '\n' && array[fd][i]) //Ищем \n
        i++;
    if (array[fd][i] == '\n')
    {
        *line = ft_strsub(array[fd], 0, i); //Вырезаю строку до \n
        temp = ft_strdup(array[fd] + i + 1); // Беру то, что идет после \n
        free(array[fd]);
        array[fd] = temp;
        if (!array[fd][0])
            ft_strdel(&array[fd]);
    }
    else if (!array[fd][i]) // Если последнее слово в файле
    {
        *line = ft_strdup(array[fd]);
        ft_strdel(&array[fd]);
    }
    return (1);
}
 
int get_next_line(int fd, char **line)
{
    static char *array[256];
    char        buffer[BUFF_SIZE + 1];
    char        *temp;
    int         ret;
 
    if (fd == -1 || !line)
        return (-1);
    while ((ret = read(fd, buffer, BUFF_SIZE)) > 0)
    {
        buffer[ret] = '\0';
        if (!array[fd])
            array[fd] = ft_strnew(1);
        temp = ft_strjoin(array[fd], buffer); //Соединяем строки, которые не содержат \n
        free(array[fd]);
        array[fd] = temp;
        if (ft_strchr(buffer, '\n'))
            break ;
    }
    if (ret == -1)
        return (-1);
    if (ret == 0 && (!array[fd] || !array[fd][0]))
        return (0);
    return (ft_cut_line(fd, line, array));
}
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
04.12.2018, 20:12
Вы array[fd] == NULL; забыли или не показали. Да и вообще ИМХО сама идея ущербна.
0
0 / 0 / 0
Регистрация: 01.12.2018
Сообщений: 6
04.12.2018, 20:16  [ТС]
Цитата Сообщение от prik Посмотреть сообщение
Вы array[fd] == NULL; забыли или не показали. Да и вообще ИМХО сама идея ущербна.
Мы можем работать сразу с несколькими файловыми дескрипторами, можем считывать сколько угодно символов из файла за раз, удобная проверка каждой строки на \n, можем работать с каждой строкой извне в других функциях. Так почему же идея ущербна?
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
04.12.2018, 20:32
Цитата Сообщение от ramory-l Посмотреть сообщение
static char *array[256];
Вот этим. Просто посмотрите где-нибудь как устроенны getline()/getdelim() не обращая внимания на потроха stdio.
0
0 / 0 / 0
Регистрация: 01.12.2018
Сообщений: 6
04.12.2018, 21:44  [ТС]
Цитата Сообщение от prik Посмотреть сообщение
Сообщение от ramory-l
static char *array[256];
Вот этим. Просто посмотрите где-нибудь как устроенны getline()/getdelim() не обращая внимания на потроха stdio.
И чем вам не нравится статическая переменная?
0
725 / 224 / 73
Регистрация: 01.03.2011
Сообщений: 643
04.12.2018, 22:09
Попробую более развернуто.
Вам нужно где-то хранить "лишние" (прочитанные вперед) данные между вызовами вашей ф-ции. Вы выбрали для этих целей массив указателей на буфера индексом в котором служит дескриптор файла которому принадлежат данные. Это уже как минимум, требует еще одной функции которою пользователь должен дергать совместно с close() на случай если файл закрывают раньше EOF. Про dup*() и тп. тоже не забываем. Получается, что бы сделать все аккуратно, требуется написать кучу оберток. По моему гораздо проще вернуться к предыдущему варианту, либо отдать этот буфер пользователю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.12.2018, 22:09
Помогаю со студенческими работами здесь

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

Чтение данных из файла и работа с ними
Может ли кто нибудь помочь? Нужно в Visual Studio 2010 написать программу, которая будет из файла читать определённые значения...

Считывание строк с файла
с помощью QTextStream и функции readline() пытаюсь считывать строки, но оно считывает лиш до пробела.Есть ли какой нибуть вариант типа...

Считывание строк из файла
Здравствуйте уважаемые форумчане! Возник вопрос по Action Script. Необходимо из txt файла(либо любого другого) построчно считать данные в...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru