Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 226, средняя оценка - 4.81
.::.DIMA.::.
143 / 143 / 4
Регистрация: 26.10.2008
Сообщений: 782
#1

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

12.01.2009, 02:51. Просмотров 28413. Ответов 23

Как считать строки из файла в массив. Если в файле одна строка, то нет проблем, но если несколько, то при использовании функции fgets считывается только первая строка,
если fscanf, то же самое, если while (! feof (fin)) fscanf …, то копируется крайняя строка файла. Может кто – нибудь подсказать как это сделать без использования ofstream и т.д.
И ещё вопрос, в чём отличие fscanf (fin, "%s", &str); от fscanf (fin, "%s", str); работает и так и так, только в первом случае с использованием взятия адреса str.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.01.2009, 02:51
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как считать строки из файла, если там больше одной строки? (C++):

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

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

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

Как считать строки с символом новой строки? - C++
Здравствуйте. мне нужно скопировать/вставить в консоль n-ое количество строк, каждая из которых заканчивается символом новой строки: ...

Как поменять знак элементов матрицы, и как вычесть элементы одной строки из другой строки? - C++
matrica = matrica - matrica; почему не получается???, не умножение на -1=(

EAccessViolation, если длина строки больше 14 - C++
Здравствуйте! Сперва простой код: void cyr_print(const char* text) { const int n = strlen(text); char *buf = new char; ...

23
Mecid
680 / 229 / 4
Регистрация: 15.10.2007
Сообщений: 1,247
12.01.2009, 03:01 #2
Ничем не отличается 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
.::.DIMA.::.
143 / 143 / 4
Регистрация: 26.10.2008
Сообщений: 782
13.01.2009, 02:24  [ТС] #3
Если в файле меньше данных, чем объявлено
Код
fread(buf,1,511,f);
то есть в файле записано не 511 символов, а только:
abc
abc
, то считается это abc abc, а дальше идут какие-то символы. Как это исправить?

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

Добавлено через 22 часа 32 минуты 22 секунды
А можно как-нибудь по другому?
0
accept
4825 / 3246 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
13.01.2009, 03:09 #4
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
.::.DIMA.::.
143 / 143 / 4
Регистрация: 26.10.2008
Сообщений: 782
14.01.2009, 00:57  [ТС] #5
Спасибо!
0
terlan
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
11.08.2009, 13:04 #6
Цитата Сообщение от 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
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
11.08.2009, 13:07 #7
Цитата Сообщение от terlan Посмотреть сообщение
а если размер файла заранее не известен
или С++ вектор используйте. или С-функции, отвечающие за перераспределение памяти.
0
terlan
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
11.08.2009, 13:19 #8
Цитата Сообщение от zim22 Посмотреть сообщение
или С++ вектор используйте. или С-функции, отвечающие за перераспределение памяти.
если я правильно понял, то надо использовать realloc() после каждой прочитанной строки?
Мне нужен именнос С
0
Gravity
564 / 558 / 39
Регистрация: 29.01.2009
Сообщений: 1,274
11.08.2009, 13:46 #9
Кому-то когда-то писал такое.
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
zim22
depict1
276 / 141 / 2
Регистрация: 11.07.2009
Сообщений: 606
11.08.2009, 13:48 #10
Цитата Сообщение от terlan Посмотреть сообщение
если я правильно понял, то надо использовать realloc() после каждой прочитанной строки?
походу - да. я в Си не силён.
если вам не нужен будет произвольный доступ к элементам массива - то можно использовать структуру "односвязный список". и не нужно будет reallocation делать.
минусы:
1) дополнительные затраты памяти на указатель для каждого узла.
2) последовательный доступ к элементам.
0
terlan
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
11.08.2009, 14:04 #11
zim22, Gravity, спасибо за ответы
0
-=ЮрА=-
Заблокирован
Автор FAQ
11.08.2009, 14:32 #12
Поробовал по своему на проблемку посмотреть, вот что вышло
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
Миниатюры
Как считать строки из файла, если там больше одной строки?  
accept
4825 / 3246 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
12.08.2009, 03:25 #13
Цитата Сообщение от 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
terlan
0 / 0 / 0
Регистрация: 11.08.2009
Сообщений: 16
14.08.2009, 16:11 #14
всем спасибо за ответы, взял за основу такой вариант:

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
accept
4825 / 3246 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
17.08.2009, 07:22 #15
пропустил
C
1
if (fseek(ifp, 0L, SEEK_SET))
0
17.08.2009, 07:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.08.2009, 07:22
Привет! Вот еще темы с ответами:

Напечатать слова из заданной строки, имеющие больше одной буквы «е» - C++
Дана строка. На печать выдать слова, имеющие больше одной буквы «е». #include &lt;iostream&gt; #include &lt;conio.h&gt; int main() { ...

Вывести слова из заданной строки, имеющие больше одной буквы «е» - C++
Дана строка. На печать выдать слова, имеющие больше одной буквы «е». С++ Помогите пожалуйста Добавлено через 7 минут help ...

Считать строки из файла в массив ++ - C++
Напишите программный код для считывания строк файла в элементы массива. Заранее спасибо!

Считать длину строки текстового файла - C++
Есть квадратная матрица, которая заполняется данными из файла. Если размерность матрицы больше, чем объём данных в файле, то нужно...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru