Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Считывание строк из файла на С 
V
    Опции темы
djamshud
Дата 6.1.2010, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Код

#define _GNU_SOURCE
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);


Это сишная функция, но, как я писал, ГНУтое расширение, т.е. не кроссплатформенно.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
Powerhead77
Дата 6.1.2010, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 1.1.2010

Репутация: нет
Всего: нет



Код
   while (!infile.eof()){
        infile.getline(str,255);      // считываем строку из файла
for (i; i<strlen(str);i++){ //определяем длинну строки            
str[i] = tolower(str[i]); //переводим все символы в строчные буквы                
if (str[i]=='#'||str[i]==';'){str[i]='\0'; break;}  //отсекаем коментарий (#;)
if (str[i]=='    '){str[i]=' ';} //подменяем символы табуляции на пробелы    
}

    }


Видимо не в тему. 
Считываем строку в буфер char str[]. Далее определяем длинну считанной строки и обрабатываем как нам надо.


Модератор: не забываем пользоваться кнопочкой "Код"

Это сообщение отредактировал(а) bsa - 10.1.2010, 17:07
PM MAIL   Вверх
NetJunky
  Дата 10.1.2010, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 277
Регистрация: 11.5.2008
Где: Tallinn

Репутация: нет
Всего: 0



Powerhead77, табуляцию можно было вроде сделать через \t.

Вопрос такого характера вроде всё по этойже тематике.
Если всёже не пользовать getline, а посимвольное считывание.
Вот например. Имею файл, в нём матрица определённого размера. Между каждым значением ячейки матрицы, в файле может быть один или более пробелов.
Код

            getSize = (char*)malloc(sizeof(char));
            i = 0;
            j = 0;
            z = 0;
            while(!feof(in)) {
                c = fgetc(in);
                if(c == '\n') {
                    if(z == mSize) {
                        break;
                    }
                    tmp = "";
                    tmp = strtok(getSize, " ");
                    for(j = 0; j <= mSize; j++) {
                        TSPmatrix[z][j] = atoi(tmp);
                        tmp = strtok(NULL, " ");
                    }
                    z++;
                    free(getSize);
                    i = 0;
                    getSize = (char*)malloc(sizeof(char));
                } else {
                    getSize[i] = c;
                    i++;
#ifdef DEBUG
    printf("%c\n", c);
#endif
                    getSize = (char*)realloc(getSize, sizeof(char) + i);
                }
            }
            free(getSize);

Но данный вариант никак не получается из-за того, что чтобы atoi грамотно перевёл, после каждого значения должен стоять знак конца строки '\0'.

Пример матрицы:
Код

0 128 71 85 185 257 232 193 199 25 130 65 171
128 0 91 62 58 161 108 151 97 126 48 179 72
71 91 0 29 149 252 199 212 143 89 149 136 163
85 62 29 0 120 223 170 195 114 89 110 143 134
185 58 149 120 0 107 50 98 85 165 56 215 14
257 161 252 223 107 0 48 99 129 237 128 287 93
232 108 199 170 50 48 0 148 84 212 106 262 64
193 151 212 195 98 99 148 0 183 174 101 223 84
199 97 143 114 85 129 84 183 0 203 130 257 99
25 126 89 89 165 237 212 174 203 0 107 54 151
130 48 149 110 56 128 106 101 130 107 0 160 42
65 179 136 143 215 287 262 223 257 54 160 0 201
171 72 163 134 14 93 64 84 99 151 42 201 0


Возможно в данном примере нету таких мест, где более одного пробела, но такое надо рассматривать.

Есть ли у кого-то предложения, как данное содержимое грамотно считать в двумерный динамический массив для которого память на этом этапе уже выдана?

Выше, код того, как я пытался.

Это сообщение отредактировал(а) NetJunky - 10.1.2010, 19:37


--------------------
Sleep, those little slices of death; Oh how I loathe them. © Edgar Allan Poe
Таллиннцы http://vingrad.ru/groups.php?action=group_...mp;group_id=139

Для записи данных объёмом 1 Терабайт на бумагу, нужно срубить 50000 деревьев.
PM MAIL WWW ICQ Skype MSN   Вверх
bsa
Дата 10.1.2010, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



а почему нельзя воспользоваться scanf/fscanf/sscanf со спецификатором %d"?
PM   Вверх
Dayx
Дата 10.1.2010, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 29.10.2009

Репутация: нет
Всего: нет



Много лет назад столкнулся с проблемой чтения разных строк.
Ну и создал себе такую маленькую функцию.
С тех пор горя не знаю...
Код

char *fgm(FILE *f)  /* Чтение строки с выделением памяти  */
{ char *b;  int c, j=0, l=81;

   if (f==NULL || feof(f)) return(NULL);
   b = malloc(l);
a: c = getc(f);
   if (c=='\n' || c==EOF) {
       b[j++] = '\0';
       if (j!=l) b = realloc(b,j);  // Чтоб лишнего не брать
       return(b);
   }
   if (j >= l-1) {
     l += 80;
     b = realloc(b,l);
   }
   b[j++] = c;
   goto a;
}

Конечно, надо еще проверять удачность выполнения malloc и realloc.
Но это уж каждый делает по своему вкусу...

PM MAIL   Вверх
bsa
Дата 10.1.2010, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Велосипедисты, блин. Тогда уж так:
Код
size_t getline(char **lineptr, size_t *n, FILE *stream)
{
   if ( !(lineptr && n && stream) ) {
       errno = EINVAL;
       return -1;
   }
   if ( *lineptr == NULL )
      *n = 0;
   else if (*n > 0)
      **lineptr = '\0';
   size_t pos = 0;
   for(; !feof(stream); ) { //пока файл не кончился
      if (pos >= *n) { 
          if (n == 0)
             n = 64;  //минимальный размер буфера, полностью выделяемого функцией
          else
             *n *= 2; //размер следующего буфера будет в 2 раза больше текущего
          *lineptr = (char*)realloc(*lineptr, *n); //увеличиваем буфер
          (*lineptr)[pos] = '\0'; //на всякий случай
      }
      fgets(*lineptr + pos, *n - pos, stream);
      pos += strlen(*lineptr + pos); //смещаем позицию на количество считанных символов
      if  ( (pos > 0) && ( (*lineptr)[pos - 1] == '\n' ) ) //если были считаны данные и последний символ строки равен '\n'
         return pos; //то строка считана полностью, возвращаем количество считанных символов
   }
   return -1; //возвращаем индикатор ошибки
}

PM   Вверх
Dayx
Дата 12.1.2010, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 29.10.2009

Репутация: нет
Всего: нет



Цитата(bsa @  10.1.2010,  21:28 Найти цитируемый пост)
Велосипедисты, блин. 

Но в то время колеса у велосипедов были квадратные!
Все равно, спасибо
PM MAIL   Вверх
bsa
Дата 13.1.2010, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(Dayx @  12.1.2010,  23:12 Найти цитируемый пост)
Но в то время колеса у велосипедов были квадратные!
мне вообще непонятно, почему использовался goto вместо цикла (for или do/while)? Не слышал, что новичкам goto строго противопоказан?

PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0943 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.