Форум русскоязычного сообщества Ubuntu


Получить помощь и пообщаться с другими пользователями Ubuntu можно
на irc канале #ubuntu-ru в сети Freenode
и в Jabber конференции ubuntu@conference.jabber.ru

Автор Тема: Работа со строками  (Прочитано 1117 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Robotex

  • Автор темы
  • Любитель
  • *
  • Сообщений: 85
    • Просмотр профиля
Работа со строками
« : 15 Декабря 2008, 03:34:39 »
Пишу курсак на С. Разрабатываю файловую систему. Никак не удается реализовать чтение из файла (запись, хоть через ректальное отверстие, но работает).

Вот функция:
char * readf(int node, char * buff, int size, int pos)
{
 
  char block[SuperBlock.BlockSize];
  //char block;
  char * buf = new char[SuperBlock.BlockSize*32];
  buff = new char[SuperBlock.BlockSize*32];
  i_node Node;
  FILE * f;
  f = fopen(DISKDRIVE, "r+w");
  fseek(f,0L,SEEK_SET);
  int size2 = size;
  fseek(f, SuperBlock.I_nodeStart+node*sizeof(i_node), SEEK_SET);
  fread(&Node, sizeof(i_node), 1, f);
 
  int j = 0;
  int i = 0;
  int readed = 0;
  int pointer = 0;
  int block_num = 0;
 
  block_num = pos/SuperBlock.BlockSize;
 
  if(Node.Blocks[block_num] != 65535)
  {
    if(pos>block_num*SuperBlock.BlockSize)
    {
      pos -= block_num*SuperBlock.BlockSize;
    }
  }
  else
  {
    block_num = 0;
    pos = 0;
  }

  i=pos;
  for(j=block_num;Node.Blocks[j] != 65535, readed<size;j++)
  {

   
    fseek(f, SuperBlock.BlockStart+Node.Blocks[j]*SuperBlock.BlockSize, SEEK_SET);
    fread(&block, SuperBlock.BlockSize, 1, f);
   
    while(i < SuperBlock.BlockSize && readed<size)
    {     
      buf[pointer] = block[i];
    //buf++;
      buf[pointer+1] = '\0';
      pointer++;
      i++;
      readed++;
    }

    i = 0;
  }
  strcpy(buff, buf);
  fclose(f);
  return buf;
}
Она то работает (не спрашивайте меня что я курил перед написанием, этот код плод бессонных ночей и бесконечных Segmentation fault), но считанную информацию, она возвращает через return. Но хотелось бы реализовать возврат информации через аргумент-указатель, а через return возвращать коды ошибок.
Заранее благодарен за помощь.

Оффлайн Robotex

  • Автор темы
  • Любитель
  • *
  • Сообщений: 85
    • Просмотр профиля
Re: Работа со строками
« Ответ #1 : 15 Декабря 2008, 03:35:59 »
Да и еще, как видите она возвращает значение в виде char *. Никак не пойму, как сделать работу с void указателями, чтобы можно было считывать не только строки, но и числовые значения...

Оффлайн axe

  • Старожил
  • *
  • Сообщений: 1203
    • Просмотр профиля
Re: Работа со строками
« Ответ #2 : 15 Декабря 2008, 03:51:19 »
Прямо скажем, код мутноватый. Не понял, зачем в нынешнем состоянии нужен входной параметр buff.

Вообще, если я правильно понимаю, чего ты хочешь, то делается примерно так (как, собственно, и сделан весь классический ввод-вывод, включая сокеты):
на вход идет 3 параметра:
1) fd -  дескриптор файла
2) buf -  буфер, куда читать
3) size - размер буфера.

Фишка в том, что буфер размера не менее, чем size, выделяется не внутри функции read, а в клиентском коде. Т.е. псевдо-C использования такой:
char buf[100]; // Буфер УЖЕ выделен на стеке
int readBytes = read(fd, buf, 100);  // Read просто копирует туда данные
Возвращается либо значение от 0 до size (это сколько реально было прочитано), либо отрицательное в случае ошибки.

Насчет проблемы с интами и void* тоже не понял. Что мешает указатель-на-войд привести к указателю-на-то-что-надо?

Вообще, просто складывается впечатление, что маловато опыта в C. Но, с другой стороны, именно так он и набирается)

Оффлайн Robotex

  • Автор темы
  • Любитель
  • *
  • Сообщений: 85
    • Просмотр профиля
Re: Работа со строками
« Ответ #3 : 15 Декабря 2008, 03:55:55 »
Ну входной параметр нужен, поскольку пытаюсь переделать чтоб выход был именно в него.

Легко сказать, да не легко сделать. В этом коде вообще какая-то мистика. Если убрать выделение памяти внутри функции, то выскакивает Segmentation fault. А так как есть, память освобождается при возврате и на выходи ересь... Ужс. У меня уже мозк кипит. Не поспите неделю, еще и не такое напишете...

Оффлайн axe

  • Старожил
  • *
  • Сообщений: 1203
    • Просмотр профиля
Re: Работа со строками
« Ответ #4 : 15 Декабря 2008, 04:09:02 »
насчт претензий к коду - без обид) что вижу то пою, как говорится)

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

есть подозрение, что вот тут:
    while(i < SuperBlock.BlockSize && readed<size)
    {     
      buf[pointer] = block[i];
    //buf++;
      buf[pointer+1] = '\0';        <----- ДА, ВОТ ТУТ!!!!
      pointer++;
ты пишешь за границу буфера размером size. Внутри функции ты буфер выделяешь с запасом - чтобы было кратно BlockSize, поэтому там все нормально.

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: Работа со строками
« Ответ #5 : 15 Декабря 2008, 06:21:11 »
Robotex, ммм.. жескач. еще один хардкор прогер.
я тебе могу сказать чего ты вообще не курил. ты не курил книг по устройству и принципам работы компьютеров, уж тем более не курил про организацию ФС.
Но это все хренотень, главное ты не курил ни одного мануала.
man open, read, write, close, malloc, realloc, free  почитай (в инете есть переведенные на русский, если англицкий для тебя мутноват).
почитай про управление памятью чтоли... а то я боюсь что ты ни когда не выберешься за пределы printf("hello, world\n"); и тем более до создания своей ФС.

P.S. хорошо хоть свою ОС не начал писать. (хотя думаю что твой сосед по парте уже начал этот мега проэкт, а ты помогаешь ему с ФС) смешно мля. не позорьтесь такими заявами. особенно спрашивая тривиальные вещи.

Оффлайн Robotex

  • Автор темы
  • Любитель
  • *
  • Сообщений: 85
    • Просмотр профиля
Re: Работа со строками
« Ответ #6 : 15 Декабря 2008, 10:52:40 »
Robotex, ммм.. жескач. еще один хардкор прогер.
я тебе могу сказать чего ты вообще не курил. ты не курил книг по устройству и принципам работы компьютеров, уж тем более не курил про организацию ФС.
Но это все хренотень, главное ты не курил ни одного мануала.
man open, read, write, close, malloc, realloc, free  почитай (в инете есть переведенные на русский, если англицкий для тебя мутноват).
почитай про управление памятью чтоли... а то я боюсь что ты ни когда не выберешься за пределы printf("hello, world\n"); и тем более до создания своей ФС.
не хочешь помочь - не пиши вообще. Что за привычка - писать не читая поста. Написано же, что курсач. Оно мне надо? В гробу я видал эту ФС, а курсач за жопу хватает. Языком все мастера шевелить, а помочь еденицы могут.

axe, спасибо, сейчас попробую...

Оффлайн wl

  • Старожил
  • *
  • Сообщений: 1393
    • Просмотр профиля
Re: Работа со строками
« Ответ #7 : 15 Декабря 2008, 11:02:12 »
Вместо strcpy надо использовать memcpy, первая функция копирует данные до '\0', а вторая - сколько скажут.
Я могу порекомендовать использовать valgrind, но, боюсь, это будет пушка для стрельбы по воробьям, которая своей массой просто задавит.
На свете феньки есть такие, брат Горацио, которых лохи просто не секут. (Шекспир, "Гамлет", вольный перевод)

Оффлайн Robotex

  • Автор темы
  • Любитель
  • *
  • Сообщений: 85
    • Просмотр профиля
Re: Работа со строками
« Ответ #8 : 15 Декабря 2008, 11:11:02 »
Удалил, но все равно падает:
    while(i < SuperBlock.BlockSize && readed<size)
    {     
      buf[pointer] = block[i];        <----- А МОЖЕТ ПРОБЛЕМА ТУТ?
    //buf++;
      //buf[pointer+1] = '\0';        <----- ДА, ВОТ ТУТ!!!!
      pointer++;
Оно походу в любом случае будет писать куда попало, поскольку память не выделена заранее... Но strcat тоже вызывает падение. И strcpy. И memcpy.

Оффлайн Robotex

  • Автор темы
  • Любитель
  • *
  • Сообщений: 85
    • Просмотр профиля
Re: Работа со строками
« Ответ #9 : 15 Декабря 2008, 11:50:24 »
Все стало еще интереснее:
char * readf(int node, char* buff, int size, int pos)
{
 
  char block[SuperBlock.BlockSize];
  //char block;
  char * buf = new char[SuperBlock.BlockSize*32];
  buff = new char[SuperBlock.BlockSize*32];
  i_node Node;
  FILE * f;
  f = fopen(DISKDRIVE, "r+w");
  fseek(f,0L,SEEK_SET);
  int size2 = size;
  fseek(f, SuperBlock.I_nodeStart+node*sizeof(i_node), SEEK_SET);
  fread(&Node, sizeof(i_node), 1, f);
 
  int j = 0;
  int i = 0;
  int readed = 0;
  int pointer = 0;
  int block_num = 0;
 
  block_num = pos/SuperBlock.BlockSize;
 
  if(Node.Blocks[block_num] != 65535)
  {
    if(pos>block_num*SuperBlock.BlockSize)
    {
      pos -= block_num*SuperBlock.BlockSize;
    }
  }
  else
  {
    block_num = 0;
    pos = 0;
  }

  i=pos;
  for(j=block_num;Node.Blocks[j] != 65535, readed<size;j++)
  {

   
    fseek(f, SuperBlock.BlockStart+Node.Blocks[j]*SuperBlock.BlockSize, SEEK_SET);
    fread(&block, SuperBlock.BlockSize, 1, f);
   
    while(i < SuperBlock.BlockSize && readed<size)
    {     
      buf[pointer] = block[i];
    //buf++;
      buf[pointer+1] = '\0';
      pointer++;
      i++;
      readed++;
    }

    i = 0;
  }
  //memcpy(buff, buf, size);
  //printf("BUFF: %s\n", buff);
  fclose(f);
  return buf;
}
char * read_file(int size, int desc)
{
  char * b, *c;
  if(OpenedFiles[desc].Node.N != -1 && desc < MAX_OPEN_FILES && desc > 0)
  {
    strcpy(c, readf(OpenedFiles[desc].Node.N, b, OpenedFiles[desc].Node.Size, OpenedFiles[desc].Pointer));
    return c;
  }
}
если в коде программы вызвать readf, то все нормально считается. А если read_file, то прога падает. Причем падение вызывает, что-то в середине readf

 

Страница сгенерирована за 0.02 секунд. Запросов: 22.