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

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

12.01.2009, 02:51. Показов 33969. Ответов 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
684 / 233 / 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
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru