LINUX.ORG.RU

массив из файла в память =(


0

0

Загибаюсь! Помогите.
есть файл вида

1,0,1,1
1,0,0,1
1,1,1,0
1,1,1,1

(квадратный массив из ноликов и еденичек,
разделённых запятыми).

Мне всего лишь надо его из файла в память.
Сделал так (только, млин, не бейте за код)

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
FILE *fd;
int n=0;
char *array;
char name[100], temp[1];
printf("Enter name of file: ");
gets(name);
if (fd=fopen(name,"r")==NULL) printf("Invalid file name.\n");

while (temp[1]!='\0')
{
fgets(temp,1,fd);
if (temp[1]!=',') ++n;
}
array=malloc(sizeof(char)*n*n);
fseek(fd,0L,SEEK_SET);
for (int i=0; i<n; i++)
for (int j=0; j<n; j++)
{
fgets(temp,1,fd);
if (temp[1]!=',' && temp[1]!='\0') array[i][j]=temp[1];
}
free(array);
close(fd);
return(0);
}

не работает =(. Что я б*я не так делаю?..


ну если закрыть глаза на возможное переполнение буфера, то там например такая ошибка:

char temp[1];

к нему можно обращаться только temp[0]. temp[1] это уже за перделами массива.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

гут, тут я действительно жестоко ступил, да и на переполнение закроем глаза всё же..

попробуй поменяй trmp[1] на temp[0], а потом попытайся скомпилировать. Не работает.

pisun
() автор топика

если файл не большой, то не проще ли его отобразить в память целиком (mmap/munmap) и так анализировать его содержимое?

corpus
()

pisun(*) (14.03.2005 15:02:30):

Это шутка такая?

Твой код не будет работать. Вообще. Он просто бессмысленный. Почитай что-нибудь про Це.

Die-Hard ★★★★★
()
Ответ на: комментарий от pisun

/*Прикалываться - так прикалываться...*/

#include <stdio.h>
#include <math.h>

size_t load_0(FILE* f, char** array, size_t size)
{
   int c = fgetc(f);
   if(c == EOF) 
   {
      *array = (char*)malloc(size);
      return size;
   }
   else
   {
      size_t res = 0;
      if(c == '0' || c == '1')
      {
        res = load_0(f,array,size+1);
        (*array)[size] = c;
      } else res = load_0(f,array,size);
      return res;
   }
}

int main(int ac, char** av)
{
    FILE *f = 0;
    char *array = 0;
    size_t size = 0, cols = 0, i = 0;
    
    
    if(ac == 2) f = fopen(av[1],"r"); else return 1;
    
    if (f == 0) printf("Invalid file name: %s\n",av[1]);
    else
    {
       size = load_0(f,&array,0); cols = (size_t)sqrt(size);

       for(i = 0; i < size; ++i)  printf("%c%c",array[i],((i+1)%cols? ',' : '\n'));

       if(array) free(array);
    }

    return 0;
}

anonymous
()
Ответ на: комментарий от pisun

Я просто не понимаю, чего ты хочешь от этого набора синтаксически неверных конструкций.

Что ты хочешь, например, сказать строчкой

if (fd=fopen(name,"r")==NULL) printf("Invalid file name.\n");

?? (ок, тут, наверное, if ( (fd=fopen(name,"r"))==NULL) -- все равно, так никогда не откроешь файл! В name надо было '\n' откусывать).

Что ты хочешь от while (temp[1]!='\0')

Что такое array[i][j]=temp[1];

???

Вообще, что ты понимаешь под "Мне всего лишь надо его из файла в память."?

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> if ( (fd=fopen(name,"r"))==NULL) -- все равно, так никогда не откроешь файл!
эээ.. так я так открывал его сегодня, и он открылся =).
Ладно, я дебил, тогда обьясните, КАК надо сделать.

"из файла в память", думаете, слишком хотрожопо?)
Смотри есть файл 1.txt:

1,1,1
1,0,1,

а мне нужно получить массию (размер мне не известен заранее)
в памяти (2 строки, 3 столбца). Доступно оьяснил?)

pisun
() автор топика
Ответ на: комментарий от pisun

2 pisun

> ...обьясните, КАК надо сделать.

Почитать простейшую книжку по основам Це. Кернигана с Риччи советую -- просто и доступно.

Тебе уже кинули пример. Попробуй разобраться. Но книжку все равно надо почитать.

Die-Hard ★★★★★
()
Ответ на: комментарий от pisun

Если квадратный (см свое послание) - то это не две ячейки, три столбца...

anonymous
()

Вообще-то, код не так уж и далек от работающего. Файл, в частности, открывается нормально.

Проблемы сосредоточены рядом с fgets. Во-первых, будет читаться 1-1, т.е. 0 байт. Лучше, вероятно, заменить fgets на fgetc и temp сделать просто char. Еще одна неприятность в том, что индексы будут бежать вне зависимости от того, прочли мы запятую или возврат каретки, или любимый ноль или единицу. Чтобы таких проблем не иметь, можно пойти дальше и заменить fgets (или fgetc) на fscanf.

anonymous
()
Ответ на: комментарий от anonymous

anonymous (*) (14.03.2005 18:28:10):

> Файл, в частности, открывается нормально.

Не поверил, попробовал -- действительно, если использовать gets(), то замыкающий '\n' откидывается (никогда не использовал gets()!) Но только если правильно расставить скобки.

В том виде, как приведено в оригинале, т.е.

if (fd=fopen(name,"r")==NULL) printf("Invalid file name.\n");

при вводе корректного имени в fd будет NULL, а if не сработает. Если ввести имя несуществующего файла, то if сработает, а в fd вместо указателя окажется галиматья ((int)1).

Die-Hard ★★★★★
()
Ответ на: комментарий от anonymous

anonymous (*) (14.03.2005 18:28:10):

> Вообще-то, код не так уж и далек от работающего.

Собрался домой, открыл баночку -- решил поспорить.

Во-первых, в приведенном автором коде содержаться СИНТАКСИЧЕСКИЕ ошибки. Он (код) просто не откомпилируется (что автор топика, BTW, и утверждает). Бессмыссленно спорить о СИНТАКСИЧЕСКИ неверных исходниках -- мы не в силах угадать, что автор имел в виду под той или иной фенечкой.

Итак, что автор топика ВООБЩЕ хочет?

>> Смотри есть файл 1.txt:

>>1,1,1

>>1,0,1,

>>а мне нужно получить массию (размер мне не известен заранее)

Что такое "массив -- размер мне не известен заранее"?

В Це НЕТУ таких массивов -- отсутствуют, как класс. Есть _многомерные_ массивы ФИКСИРОВАННОЙ на этапе компиляции размерности. ВСЕ! В Це ВООБЩЕ по-другому работают с многомерными структурами!

Че хочет автор?

Просто "надо его из файла в память" -- ок. При чем тут Це?

Делаем "cat thefile" -- файл отображается на экране -- ГАРАНТИРОВАННО содержание файла -- в оперативной памяти (в буферах, в экранной памяти) -- и че?

Чтобы файл в userspace память загрузить -- ok, просто грузи его посимвольно в массив. В ДАННОМ примере достаточно прочитать ПЕРВЫЙ элемент -- все будет в первой же странице (на самом деле, просто в буфере) (файл слишком мал)).

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

Вопрос -- в какую? Об этом автор топика упомянуть -- не то, чтобы забыл, а просто не понял, что ему надо об этом упомянуть...

Там поля -- целые числа? И только от 0 д 9? Или просто "квадратная матрица из целых чисел?" -- в любом случае, приведенный код далек от того, что могло бы решить любую из вышеперечисленных задач.

Или требуемая структура -- просто char'ы? Тогда, конечно, утверждение о том, что запятая -- разделитель, может быть проэксплуатировано -- но выбранный формат для хранения данных (char *) несколько не соответствует...

BTW, утверждение (IMHO) -- все, кто поняли автора топика -- найтивные ФОРТРАН-программисты. IMHO остальным объяснения просто не доступны...

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>BTW, утверждение (IMHO) -- все, кто поняли автора топика -- найтивные ФОРТРАН-программисты.
>IMHO остальным объяснения просто не доступны...
=)
Ладно, всем спасибо. Пойду читать унижку про Це.

pisun
() автор топика
Ответ на: комментарий от Die-Hard

>> Что такое "массив -- размер мне не известен заранее"?

> В Це НЕТУ таких массивов -- отсутствуют, как класс. Есть _многомерные_ массивы ФИКСИРОВАННОЙ на этапе компиляции размерности. ВСЕ!

Вы-таки будете смеяться, но в C99 они есть (размер должен быть известен на момент входа в блок, если не ошибаюсь, а не на этапе компиляции) :) Это я так, к слову...

Teak ★★★★★
()
Ответ на: комментарий от Teak

2Teak

> Вы-таки будете смеяться, но в C99 они есть

Лень лезть в C99 -- а что должен говорить sizeof на массивы НЕфиксированной размерности?

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Лень лезть в C99 -- а что должен говорить sizeof на массивы
> НЕфиксированной размерности?

AFAIR, их реальный размер во время выполнения.

int19h ★★★★
()
Ответ на: комментарий от int19h

Да уж, был немного шокирован:

Dynamic sizeof evaluation

Because C99 supports variable-length arrays (VLAs), the sizeof
operator does not necessarily evaluate to a constant
(compile-time) value. Any expression that involves applying the
sizeof operator to a VLA operand must be evaluated at runtime
(any other use of sizeof can be evaluated at compile time). For
example:

    size_t dsize(int sz)
    {
        float   arr[sz];          // VLA, dynamically allocated

        if (sz <= 0)
            return sizeof(sz);    // Evaluated at compile time
        else
            return sizeof(arr);   // Evaluated at runtime
    }

C++ does not support VLAs, so C code that applies the sizeof
operator to VLA operands will cause problems when
compiled as C++.

[C99: ╖6.5.3.4, 6.7.5, 6.7.5.2]
[C++98: ╖5.3, 5.3.3]

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Да уж, был немного шокирован:

А что такого? Просто ввели в язык фичу, которая, может, и не особо
"высокоуровневая", но зато позволяет писать на нем многие вещи намного
внятней.

Я, помнится, воспользовался этим делом, когда писал курсовик по
численным методам. Нам там свободы выбора не давали - пишите на C, и
все тут. Ну я и написал =)

int19h ★★★★
()
Ответ на: комментарий от int19h

int19h:

> А что такого?

Стандарт, который во многом причесывал язык в сторону ЦеПП, оказался "утонченно" несовместим со стандартом ЦеПП.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

> Стандарт, который во многом причесывал язык в сторону ЦеПП,
> оказался "утонченно" несовместим со стандартом ЦеПП.

Вообще-то там немало вещей, которые иначе как "в пику C++" оценить
трудно - тот же комплексный тип, например, или restrict, или _Bool/bool.
Другой вопрос, что никто не заставляет ими пользоваться,

int19h ★★★★
()
Ответ на: комментарий от Die-Hard

>Да уж, был немного шокирован:

Напрасно. То что в гцц называется variable-length arrays есть совсем не то что описано в С99, но частично совместимо.

Покраёней мере так было до недавнего времени. Инфа взята из info gcc.

cvv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.