Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/170: Рейтинг темы: голосов - 170, средняя оценка - 4.57
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782

Как считать строки из файла, если там больше одной строки?

12.01.2009, 02:51. Показов 33907. Ответов 23

Студворк — интернет-сервис помощи студентам
Как считать строки из файла в массив. Если в файле одна строка, то нет проблем, но если несколько, то при использовании функции fgets считывается только первая строка,
если fscanf, то же самое, если while (! feof (fin)) fscanf …, то копируется крайняя строка файла. Может кто – нибудь подсказать как это сделать без использования ofstream и т.д.
И ещё вопрос, в чём отличие fscanf (fin, "%s", &str); от fscanf (fin, "%s", str); работает и так и так, только в первом случае с использованием взятия адреса str.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.01.2009, 02:51
Ответы с готовыми решениями:

Как считать строки из файла по одной?
есть файл в нем записаны данные, как из файла считать строки по одной?

Если результат возвращает больше одной строки, ORA-01422, как быть?
Привет, программисты! помогите пожалуйста химику)) есть большой лист ИД (>5000 строк), по этим ИД надо достать данные из таблицы, но на...

Как считать матрицу 3*3 из файла если он там задан неправильно
как считать матрицу 3*3 из файла если он там задан неправильно например в файле 4 5 6 7 8 1 2 3 4 9 8 7 а должно считать 4 5...

23
 Аватар для Mecid
683 / 232 / 16
Регистрация: 15.10.2007
Сообщений: 1,246
12.01.2009, 03:01
Ничем не отличается str=&str

Добавлено через 3 минуты 41 секунду
C++
1
2
3
4
5
6
7
8
#include <stdio.h>
int main(){
char buf[512];
FILE *f=fopen("q.txt","r");
fread(buf,1,511,f);
printf("%s\n",buf);
return 0;
}
Добавлено через 1 минуту 18 секунд
C++
1
2
3
4
5
6
7
8
 #include <stdio.h>
int main(){
char buf[512];
FILE *f=fopen("q.txt","r");
fread(buf,1,511,f);
printf("%s\n",buf);
return 0;
}
Добавлено через 36 секунд
C++
1
2
3
4
5
6
7
8
#include <stdio.h>
int main(){
char buf[512];
FILE *f=fopen("q.txt","r");
fread(buf,1,511,f);
printf("%s\n",buf);
return 0;
}
1
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782
13.01.2009, 02:24  [ТС]
Если в файле меньше данных, чем объявлено
Code
1
fread(buf,1,511,f);
то есть в файле записано не 511 символов, а только:
abc
abc
, то считается это abc abc, а дальше идут какие-то символы. Как это исправить?

Добавлено через 41 минуту 43 секунды
Неправильно написал, если 511 исправить, например, на 1, то считается 1 символ, а дальше опять какие-то символы. Может это из-за того, что fread обычно используется при работе и бинарными файлами?

Добавлено через 22 часа 32 минуты 22 секунды
А можно как-нибудь по другому?
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
13.01.2009, 03:09
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
#include <stdio.h>
 
#define MAXBUF  5000   /* максимальная длина буфера */
 
/* считывает строки из файла в массив */
main()
{
    FILE *fp;
    char buf[MAXBUF], *p;
    int c;
    const char *fname = "file.txt";
    
    if ((fp = fopen(fname, "rb")) == NULL)
        return 1;
    for (p = buf; p-buf < MAXBUF-1 && (c = getc(fp)) != EOF; p++)
        *p = c;
    *p = '\0';
    printf("%s", buf);
    fclose(fp);
    return 0;
}
Добавлено через 3 минуты 19 секунд
когда идут какие-то символы это значит что нуль-символ в конце не записан (его надо специально записывать в буфер)
0
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782
14.01.2009, 00:57  [ТС]
Спасибо!
0
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
11.08.2009, 13:04
Цитата Сообщение от accept Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
#include <stdio.h>
 
#define MAXBUF  5000   /* максимальная длина буфера */
 
/* считывает строки из файла в массив */
main()
{
    FILE *fp;
    char buf[MAXBUF], *p;
    int c;
    const char *fname = "file.txt";
    
    if ((fp = fopen(fname, "rb")) == NULL)
        return 1;
    for (p = buf; p-buf < MAXBUF-1 && (c = getc(fp)) != EOF; p++)
        *p = c;
    *p = '\0';
    printf("%s", buf);
    fclose(fp);
    return 0;
}
Добавлено через 3 минуты 19 секунд
когда идут какие-то символы это значит что нуль-символ в конце не записан (его надо специально записывать в буфер)
а если размер файла заранее не известен. Например, MAXBUF может колебаться от 10 до 100.000.000.000?
Как быть в таком случае?
0
depict1
 Аватар для zim22
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
11.08.2009, 13:07
Цитата Сообщение от terlan Посмотреть сообщение
а если размер файла заранее не известен
или С++ вектор используйте. или С-функции, отвечающие за перераспределение памяти.
0
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
11.08.2009, 13:19
Цитата Сообщение от zim22 Посмотреть сообщение
или С++ вектор используйте. или С-функции, отвечающие за перераспределение памяти.
если я правильно понял, то надо использовать realloc() после каждой прочитанной строки?
Мне нужен именнос С
0
 Аватар для Gravity
577 / 571 / 65
Регистрация: 29.01.2009
Сообщений: 1,274
11.08.2009, 13:46
Кому-то когда-то писал такое.
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 1024
 
int main(void)
{
    FILE *ifp;
    int i, maxline = 8;
    char **lines, **p, buf[MAXLEN];
    
    if( (ifp = fopen("input.txt", "r")) == NULL) {
        perror("fopen");
        return 1;
    }
    if( (lines = (char **) malloc(sizeof(char *) * maxline)) == NULL) {
        perror("malloc");
        return 1;
    }
    for(i = 0; ; i++) {
        if(i >= maxline) {
            maxline *= 2;
            if( (p = (char **) realloc(lines, sizeof(char *) * maxline)) == NULL) {
                perror("realloc");
                return 1;
            }
            lines = p;
        }
        if( (lines[i] = (char *) malloc(MAXLEN)) == NULL) {
            perror("malloc");
            return 1;
        }
        if(fgets(buf, sizeof(buf), ifp) == NULL)
            break;
        strcpy(lines[i], buf);
    }
    fclose(ifp);
    maxline = i + 1;
    for(i = 0; i < maxline; i++)
        printf("%s", lines[i]);
    return 0;
}
1
depict1
 Аватар для zim22
281 / 146 / 4
Регистрация: 11.07.2009
Сообщений: 606
11.08.2009, 13:48
Цитата Сообщение от terlan Посмотреть сообщение
если я правильно понял, то надо использовать realloc() после каждой прочитанной строки?
походу - да. я в Си не силён.
если вам не нужен будет произвольный доступ к элементам массива - то можно использовать структуру "односвязный список". и не нужно будет reallocation делать.
минусы:
1) дополнительные затраты памяти на указатель для каждого узла.
2) последовательный доступ к элементам.
0
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
11.08.2009, 14:04
zim22, Gravity, спасибо за ответы
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.08.2009, 14:32
Поробовал по своему на проблемку посмотреть, вот что вышло
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
#include <windows.h>
#include <shlobj.h>
#include <stdio.h>
 
int * iPos = (int *)malloc(sizeof(int));
char * str = (char *)malloc(sizeof(char));
 
LPTSTR SelectFile();
//Подсчёт числа строк в текстовом блоке
//под строкой понимаю текст между символами '\n' [строка] '\n'
//iPos - содержит индексы символов '\n' в блоке str
int GetNumStrings(LPTSTR str);
 
void main()
{
    FILE * f;
    int nStrings = 0,i;
    long fLen = -1;
    char sPath[MAX_PATH];sPath[0] = '\0';
    if(sprintf(sPath,SelectFile()))
    {
        if((f = fopen(sPath,"rb+")))
        {
            fseek(f,0,SEEK_END);
            fLen = ftell(f);
            fseek(f,0,SEEK_SET);
            str = (char *)realloc(str,fLen);
            fread(str,1,fLen,f);
            str[fLen - 1] = '\0';
            fclose(f);
            nStrings = GetNumStrings(str);
            printf("File : %s\r\n",sPath);
            printf("consist of %d strings\r\n",nStrings);
            for(int i = nStrings - 1; 0 <= i; i--)
            {
                printf("[string %d] : %s\r\n",nStrings - i, str + iPos[i]);
                str[iPos[i]] = '\0';
            }
            iPos = (int *)realloc((void *)iPos,sizeof(int));
            if(str)
                str = (char *)realloc(str,sizeof(char));
        }
    }
    printf("Press NUM1 to choose next file\r\n");
    scanf("%d",&i);
    if(i == 1)
        main();
}
 
LPTSTR SelectFile()
{
    char sPath[MAX_PATH];sPath[0] = '\0';
    LPCITEMIDLIST lpItemDList;
    BROWSEINFO bi = {NULL, NULL, sPath,
       "Выберите файл для обработки",
        BIF_DONTGOBELOWDOMAIN|BIF_BROWSEINCLUDEFILES,
        NULL,
        NULL,
        0
    };
    if((lpItemDList=SHBrowseForFolder(&bi)))
    {
        if(SHGetPathFromIDList(lpItemDList, sPath))
            GetShortPathName((LPCTSTR)sPath,sPath,strlen(sPath));
    }
    return &sPath[0];
}
 
int GetNumStrings(LPTSTR str)
{
    int RetVal = 0;
    //Вдруг вначале текста идут символы новой строки
    while(str[0] == '\n')
        str++;
    char * chBuf = strchr(str,'\n');
    //На случай если в файле всего 1 строка
    if(!chBuf && strlen(str))
    {
        iPos[RetVal] = 0;
        RetVal++;
    }
    while(chBuf)
    {
        iPos[RetVal] = strlen(str) - strlen(chBuf);
        RetVal++;
        chBuf++;
        if(chBuf)
            chBuf = strchr(chBuf,'\n');
        iPos = (int *)realloc((void *)iPos,sizeof(int)*(RetVal + 1));
    }
    return RetVal;
}
Миниатюры
Как считать строки из файла, если там больше одной строки?  
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
12.08.2009, 03:25
Цитата Сообщение от terlan
а если размер файла заранее не известен
Цитата Сообщение от terlan
Например, MAXBUF может колебаться от 10
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
#include <stdio.h>
 
/* открывает файл, определяет его размер и выдялет буфер
   считывает файл в буфер и выводит */
int main(int argc, char *argv[])
{
    FILE *ifp;
    long fsize;
    char *pBuf, *p;
    int c;
    const char *fname = "file.txt";
    
    if (argc > 1)
        fname = *(argv+1);
    
    if ((ifp = fopen(fname, "rb")) == NULL)
        return 1;
    
    if (fseek(ifp, 0L, SEEK_END))
        return 2;
    
    fsize = ftell(ifp);
    
    printf("%ld\n", fsize);
    
    if (fseek(ifp, 0L, SEEK_SET))
        return 2;
    
    if ((pBuf = malloc(fsize)) == NULL)
        return 3;
    
    for (p = pBuf;
         (c = getc(ifp)) != EOF;
         *p = c, p++)
        ;
    *p = '\0';
    fclose(ifp);
    
    printf("%s", pBuf);
    
    free(pBuf);
    
    return 0;
}
b - обязательно

для больших файлов нужно решить
как его открыть
как выделить память под данные
0
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
14.08.2009, 16:11
всем спасибо за ответы, взял за основу такой вариант:

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
 FILE *pFile;
    const char *fName = "test.txt";
    char *content;
    long lSize;
    size_t result;
 
    if ((pFile = fopen (fName, "rb") == NULL))
    {
        fprintf (stderr, "failed to open test.txt");
        exit (1);
    }
    else
    {
        fseek (pFile , 0 , SEEK_END);
        lSize = ftell (pFile);
        rewind( pFile );
         // allocate memory to contain the whole file:
        content = (char*) malloc (sizeof(char)*lSize);
        if (content == NULL) {fputs ("Memory error",stderr); exit (2);}
 
        // copy the file into the buffer:
        result = fread (content,1,lSize,pFile);
        if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
 
        /* the whole file is now loaded in the memory buffer. */
        // terminate
        fclose (pFile);
        ...
    }
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
17.08.2009, 07:22
пропустил
C
1
if (fseek(ifp, 0L, SEEK_SET))
0
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
18.08.2009, 14:49
accept, объясни, пожалуйста.
листинг программы я взял отсюда.
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
18.08.2009, 21:59
Когда переписывал - вызов функции rewind() потерял куда-то.
Может еще чего потерял
0
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
18.08.2009, 22:07
Цитата Сообщение от odip Посмотреть сообщение
Когда переписывал - вызов функции rewind() потерял куда-то.
Может еще чего потерял
верно, пропустил
вот только не могу исправить пост со cниппетом. Подскажите, пожалуйста, как править?
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
19.08.2009, 04:20
править можно только если сообщение последнее

- добавляешь сообщение
- обновляешь (оно присоединяется к последнему)
- нажимаешь правка (добавленное удаляешь, а последнее правишь)

(ну, когда там время истекло)
0
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
19.08.2009, 08:20
Еще можно модера попросить.
Модер может править любое сообщение.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.08.2009, 08:20
Помогаю со студенческими работами здесь

Как запретить удаление строки в DataGridView, если пользователь не выбрал ни одной строки?
Здравствуйте! У меня есть datagridview и кнопка удаления записи на форме. Данные в datagridview попадают из таблицы базы данных...

Считать данные из файла от одной строки до другой
Всем привет. Задача такая: есть текстовый файл, в котором существует двумерный массив, записано все в файле так Step number= 1 ...

Можно ли отредактировать pdf файл Фотошопом если там больше одной страницы?
Есть pdf-файл. 24 страницы. На первой странице небольшая ошибка. Открыл файл Фотошопом, выбрал первую нужную страницу и подправил ластиком...

Если первый элемент строки больше некоторого заданного числа, то его следует поставить в конец строки
В матрице размером m x n для каждой строки матрицы сделать следующие действия: если первый элемент строки больше некоторого заданного...

Считать строки из файла, найти строки на определённую букву
По заданию нужно вывести данные студентов, чьи фамилии начинаются на А и математику сдали на 8 или 9. Проблема в поиске фамилии на А,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru