0 / 0 / 0
Регистрация: 21.07.2015
Сообщений: 2

Узнать размер строки в файле

18.12.2015, 21:45. Показов 8624. Ответов 4
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Необходимо узнать размер строки в файле, чтобы выделить для нее память и занести в динамический массив.
Проблема в том, что strlen не хочет работать с указателем на файл.
Можно ли это как то реализовать не создавая большой статический массив? (иначе просто смысл в динамическом массиве пропадает)
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.12.2015, 21:45
Ответы с готовыми решениями:

Как узнать размер строки как размер массива
const char* test_str = "01234\x00 789"; //очевидно, что strlen(test_str) == 5; sizeof(test_str) == 4; sizeof(*test_str) == 1; ...

Вывести на экран строки, размер которых больше среднего размера строки в файле
Ребятки....помогите пожалуйста с РГЗ!!!:cry: Организовать текстовый файл, состоящий из N строк. Вывести на экран строки, размер...

Вывести на экран строки, размер которых больше среднего размера строки в файле.
1)Организовать текстовый файл, состоящий из N строк. Вывести на экран строки, размер которых больше среднего размера строки в файле.

4
529 / 432 / 159
Регистрация: 25.11.2014
Сообщений: 1,662
18.12.2015, 21:51
Цитата Сообщение от ranrus Посмотреть сообщение
Можно ли это как то реализовать не создавая большой статический массив?
Читать в буфер определенного размера. Считать, пока не найдешь символ перевода строки. Если в считанном буфере нет такого символа, читаем следующие данные из файла и считать дальше. Но дело в том, что тебе нужно вернуться на прошлое положение в файле, чтобы свою строку уже известной длины считать полностью.
Цитата Сообщение от ranrus Посмотреть сообщение
Проблема в том, что strlen не хочет работать с указателем на файл
А если в файле 1000 строк, то размер какой строк из 1000 должна тебе strlen дать?
0
640 / 395 / 75
Регистрация: 21.09.2008
Сообщений: 1,360
18.12.2015, 23:48
Лучший ответ Сообщение было отмечено ranrus как решение

Решение

ranrus, алгоритм примерно такой:
1. Обнулить счётчик длины строки.
2. Встать на начало файла.
3. Запомнить позицию в файле. Начать считывать посимвольно из файла. Пока не достигнут перевод строки или конец файла (EOF), увеличивать счётчик строки. Когда достигли конца строки, выйти из цикла и зарезервировать память под строку функцией сalloc по счётчику длины строки +1 символ на нулевой символ (признак конца строки). Вернуться на сохранённый указатель начала строки в файле и сосчитать в буфер строку указанного размера.
4. Пропустить разделитель строки. Конец строки обозначается в DOS/Windows парой символов '\r\n' (шестнадцатеричные коды 0x0D, 0x0A), или одним символом '\n' под *nix.
5. Начать всё заново с пункта 3.
2
 Аватар для Геомеханик
838 / 641 / 940
Регистрация: 26.06.2015
Сообщений: 1,409
19.12.2015, 12:59
По простому.
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <stdio.h>
#include <string.h>
#include <malloc.h>
 
typedef struct {
    char** a;
    size_t n;
} sarray_t;
void sarray_init(sarray_t* arr);
int  sarray_open(const char* fn, sarray_t* arr);
int  sarray_save(const char* fn, sarray_t* arr);
void sarray_free(sarray_t* arr);
 
int main(void){
    size_t   i;
    sarray_t arr;
    sarray_init(&arr);
 
    if(! sarray_open("input.txt", &arr)){
        fputs("error sarray_open !\n", stderr);
        return 1;
    }
 
    for(i = 0; i < arr.n; ++i)
        puts(arr.a[i]);
 
//  sarray_save("output.txt", &arr);
    sarray_free(&arr);
    return 0;
}
 
//получение массива из строк файла
int sarray_open(const char* fn, sarray_t* arr){
    char   b[512], *p, **a, *s, *q;
    size_t k, i, m, l;
    FILE*  fp = fopen(fn, "r");
    if(fp == NULL)
        return 0;
 
    //подсчёт кол-во строк
    k = m = 0;
    i = l = 1;
    while((p = fgets(b, sizeof(b), fp)) != NULL){
        do {
            if(*p == '\n'){
                if(l > m)
                    m = l;
                i = 1;
                l = 0;
            } else if(i > 0){
                ++k;
                i = 0;
            }
            ++l;
        } while(*p++ != '\0');
    }
 
    if(! k || ! feof(fp) || (ferror(fp) != 0)){
        fclose(fp);
        return 0;
    }
    
    a = NULL;
    m = (l > m) ? l + 3 : m + 3;
    s = (char*)malloc(m * sizeof(char));
    if(s == NULL)
        goto err;
 
    a = (char**)malloc(k * sizeof(char*));
    if(a == NULL)
        goto err;
 
    i = 0;
    rewind(fp);
    while((p = fgets(s, (int)m, fp)) != NULL){
        q = s;
        for(; *p; ++p){
            if(*p == '\n' || *p == '\r')
                continue;
            *q++ = *p;
        }
        *q   = '\0';
        k    = (size_t)(q - s);
        a[i] = (char*)malloc((k + 1) * sizeof(char));
        if(a[i] == NULL)
            goto err;
 
        memcpy(a[i++], s, (k + 1) * sizeof(char));
    }
    free(s);
    fclose(fp);
 
    sarray_free(arr);
    arr->a = a;
    arr->n = i;
    return 1;
err:
    fclose(fp);
    if(s != NULL)
        free(s);
 
    if(a != NULL){
        for(k = 0; k < i; ++k)
            free(a[k]);
        free(a);
    }
    return 0;
}
 
//сохранение массива в текстовый файл
int sarray_save(const char* fn, sarray_t* arr){
    int    r;
    size_t i;
    FILE*  fp;
    if(! arr->n)
        return 0;
    
    if((fp = fopen(fn, "w+")) == NULL)
        return 0;
 
    for(r = 1, i = 0; i < arr->n; ++i){
        if(fputs(arr->a[i], fp) == EOF){
            r = 0;
            break;
        }
        if(i < (arr->n - 1))
            fputc('\n', fp);
    }
    fflush(fp);
    fclose(fp);
    return r;
}
 
//удаление двухмерного массива
void sarray_free(sarray_t* arr){
    size_t i;
    if(arr->a != NULL){
        for(i = 0; i < arr->n; ++i)
            free(arr->a[i]);
        free(arr->a);
        arr->a = NULL;
        arr->n = 0;
    }
}
 
//инициализация
void sarray_init(sarray_t* arr){
    arr->a = NULL;
    arr->n = 0;
}
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12841 / 7589 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
19.12.2015, 14:15
Когда надоест изобретать велосипед:
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
/* ANSI C 99 */
#include <glib.h>
 
int main(int argc, char ** argv) {
    if ( argc != 2 ) {
        g_print("Usage: %s <file_to_read>\n", *argv);
        return -1;
    }
    
    GError * err;
    GIOChannel * inpfile = g_io_channel_new_file(argv[1], "r", &err);
    if ( ! inpfile ) {
        g_print("%s\n", ( err ) ? err->message : "Can't open input file!");
        return 1;
    }
    
    GList * rows = NULL;
    GString * str = g_string_new("");
    
    while ( g_io_channel_read_line_string(inpfile, str, NULL, &err) == G_IO_STATUS_NORMAL )
        rows = g_list_prepend(rows, g_strdup(str->str));
    
    g_io_channel_close(inpfile);
    
    rows = g_list_reverse(rows);
    g_list_foreach(rows, (GFunc)g_print, NULL);
    
    g_list_foreach(rows, (GFunc)g_free, NULL);
    g_list_free(rows);
    
    return 0;
}
Code
1
2
3
4
5
6
7
8
9
10
11
~/cpp/glib $ gcc -std=c99 read_file.c `pkg-config --cflags --libs glib-2.0`
~/cpp/glib $ ./a.out read_file.c 
/* ANSI C 99 */
#include <glib.h>
 
int main(int argc, char ** argv) {
    if ( argc != 2 ) {
        g_print("Usage: (null) <file_to_read>\n", *argv);
        return -1;
    }
...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.12.2015, 14:15
Помогаю со студенческими работами здесь

Как узнать размер строки?
есть массив указателей string **str на объекта класс string; как узнать размер строки, записанной, например, в *str?

Узнать размер строки до её считывания
Возник вопрос связанный с выделением памяти под массив символов. Задача: считать строку в массив символов с выделением динамической...

Как узнать размер строки в пикселях?
У меня есть строка. Хочу узнать размер в пикселях. Это надо для того, чтобы потом узнав размер окна, уменьшать размер строки (в окне) до...

Можно ли изменить размер строки в файле?
У меня в файле есть строка, которая содержит баланс счета. Проблема в том, что если у меня на счету 1000 и я сниму 100, то получится 900....

Файловые потоки: узнать номер самой длинной строки и её размер
Я с файла считываю информацию, а мне нужно узнать номер самой длинной строки и её размер


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

Новые блоги и статьи
Согласованность транзакций в MongoDB
Codd 30.04.2025
MongoDB, начинавшая свой путь как классическая NoSQL система с акцентом на гибкость и масштабируемость, сильно спрогрессировала, включив в свой арсенал поддержку транзакционной согласованности. Это. . .
Продвинутый ввод-вывод в Java: NIO, NIO.2 и асинхронный I/O
Javaican 30.04.2025
Когда речь заходит о вводе-выводе в Java, классический пакет java. io долгие годы был единственным вариантом для разработчиков, но его ограничения становились всё очевиднее с ростом требований к. . .
Обнаружение объектов в реальном времени на Python с YOLO и OpenCV
AI_Generated 29.04.2025
Компьютерное зрение — одна из самых динамично развивающихся областей искусственного интеллекта. В нашем мире, где визуальная информация стала доминирующим способом коммуникации, способность машин. . .
Эффективные парсеры и токенизаторы строк на C#
UnmanagedCoder 29.04.2025
Обработка текстовых данных — частая задача в программировании, с которой сталкивается почти каждый разработчик. Парсеры и токенизаторы составляют основу множества современных приложений: от. . .
C++ в XXI веке - Эволюция языка и взгляд Бьярне Страуструпа
bytestream 29.04.2025
C++ существует уже более 45 лет с момента его первоначальной концепции. Как и было задумано, он эволюционировал, отвечая на новые вызовы, но многие разработчики продолжают использовать C++ так, будто. . .
Слабые указатели в Go: управление памятью и предотвращение утечек ресурсов
golander 29.04.2025
Управление памятью — один из краеугольных камней разработки высоконагруженных приложений. Го (Go) занимает уникальную нишу в этом вопросе, предоставляя разработчикам автоматическое управление памятью. . .
Разработка кастомных расширений для компилятора C++
NullReferenced 29.04.2025
Создание кастомных расширений для компиляторов C++ — инструмент оптимизации кода, внедрения новых языковых функций и автоматизации задач. Многие разработчики недооценивают гибкость современных. . .
Гайд по обработке исключений в C#
stackOverflow 29.04.2025
Разработка надёжного программного обеспечения невозможна без грамотной обработки исключительных ситуаций. Любая программа, независимо от её размера и сложности, может столкнуться с непредвиденными. . .
Создаем RESTful API с Laravel
Jason-Webb 28.04.2025
REST (Representational State Transfer) — это архитектурный стиль, который определяет набор принципов для создания веб-сервисов. Этот подход к построению API стал стандартом де-факто в современной. . .
Дженерики в C# - продвинутые техники
stackOverflow 28.04.2025
История дженериков началась с простой идеи — создать механизм для разработки типобезопасного кода без потери производительности. До их появления программисты использовали неуклюжие преобразования. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru