Ответы пользователя по тегу C
  • Как оптимизировать функции по скорости?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    man strnstr
    man memchr

    И может быть немного почитать гугл о строковых функциях прежде чем начинать нести чушь и клепать велики? Да, и строка короче чем 0 быть не может. :)
    Ответ написан
    Комментировать
  • На чем лучше писать на языке Си?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Gcc - значит линух. Не забывайте указывать ось. Да, есть cygwin, но использовать gcc в винде - изврат. Если в линухе работает гуй, лучше всего встроенные в IDE редакторы - Eclipse, KDevelop. Если IDE нет - можно любой редактор - большинство из них имеет подсветку синтаксиса и функции авторасстановки скобок.
    Если гуя нет, а есть только консоль - я например использую mcedit.
    Ответ написан
    Комментировать
  • Интересная задача (язык Си). Как работать с биарными файлами?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Ваша задача не на потоковое чтение, а на бинарное. То есть она должна решаться другими способами.

    Во-первых, нафиг fopen/fread/fclose - c бинарными файлами так не работают. С бинарными файлами работают через open/read/close. А если в файле фиксированная двоичная структура - обычно ее сначала описывают, потом считывают и накладывают структуру на область. Примеры дальше, случайно отправил.

    Открыть, прочитать, закрыть
    int i;
      short int handle;
      struct stat sb;
    
      char *wdir;
      if ((handle = open("/tmp/blabla.txt", O_RDONLY)) < NULL)
        {
          // Тут можно сделать обработку ошибок
          exit;
        }
       else
         stat("/tmp/blabla.txt", &sb);
    
      // Память под чтение одним вызовом + 1 байт на финальный нуль
      wdir = (char *) malloc(sb.st_size + 1);
     
      i = read(handle, wdir, sb.st_size);
      close(handle);
    
      *(wdir + sb.st_size) = '\0';
    Ответ написан
    Комментировать
  • Как разобраться с выделением памяти в массиве?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Я так понял - сперли откуда-то кусок кода, но понять, как это работает, тяму не хватает. Да и код-то фиговый.

    int** inmatr(int m,int n){
        int *matr;
        int i,j;
    
        if ((matr=(int*) сalloc(m * n, sizeof(int))) == NULL)
          {
             puts("Memory alloc error");
             exit(100);
          }
    
        for (i=0; i<m; i++){
            for (j=0;j<n;j++){
                printf("a[%d][%d] = ", i, j);
                scanf("%d", &matr[i][j]);
            }
        }
        return &matr;
    }


    Проверка успешности выделения памяти делается банально просто - если память не выделена, целевая переменная равна NULL. Выделять память не только можно, но и нужно сразу - размер матрицы же известен сразу. Только разумеется не массив указателей на целое, а массив целых.
    Возвращается адрес области, куда записали адрес области под матрицу. Хотя я бы передавал переменную (тип **int) из вызывающей функции.
    Освобождается память через free(). Но освобождение невыделенной памяти может запросто привести к SIGSEGV.
    Ответ написан
    Комментировать
  • "undefined reference to" при линковке, что делать?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    неопределенная ссылка __stack_chk_fail_local
    скрытый символ __stack_chk_fail_local не определен
    попытка окончательной компоновки потерпела неудачу: ошибочное значение
    (переведено гуглом)

    Где-то используется функция или внешняя переменная __stack_chk_fail_local, но ни в одном из обьектных файлов, переданных компоновщику данная функция/переменная не обнаружена
    Ответ написан
    3 комментария
  • Как удалить из текстового файла структуру?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Считать
    Удалить элемент
    Записать

    Если структура бинарная, там вообще все делается буквально вот в эти три действия (если структура описана заранее и есть структурный тип). Если структура текстовая, переменной длины - возможно придется потрахаться, чтобы найти границы элемента.
    Ответ написан
  • Ошибка при чтении из файла в си.Что делать?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Не надо использовать эту [beep] конструкцию while(!feof())
    От нее только проблемы. Используйте fscanf() в цикле, пока он не вернет EOF.

    Да, я знаю, что в примерах так - я сам когда-то писал по таким же примерам и потом долго матерился, не понимая, почему не работает...
    Ответ написан
    2 комментария
  • Есть ли в си конструктор по умолчанию?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    В С нет никаких конструкторов - ни по умолчанию, ни без оного. И деструкторов тоже :)

    Наверное пора организовать приз имени Дани Джена на самый глупый вопрос :)
    Ответ написан
    Комментировать
  • Выражение должно иметь типа указателя на объект. В чем суть ошибки?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Вынужден согласиться с Illia Nezhyhai - этот код - одна большая ошибка :) Причем главная ошибка в том, что у параметров функции нет типа, а следовательно компилятор предполагает, что они имеют тип int (для С, в С++ типа по умолчанию нет, попытка откомпилировать данный код вызовет ошибку). Поэтому разумеется выражение arr[i][j] = что-то там будет неверным.

    Во-первых, все параметры функций всегда должны типизироваться - это Вас и спасет от таких вот нелепых ошибок и напомнит, что передается в функцию, если Вы по собственной лени не напишете комментарий с описанием этого
    Во-вторых, документирование передаваемых параметров и присвоение переменным нормальных имен, а не i,j,k - поможет и другому, кто будет Ваш код читать, и Вам самому - когда Вы в него полезете через год.
    Ответ написан
    4 комментария
  • Какую использовать среду разработки C под Windows?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Хм. А почему никто не посоветовал Eclipse?
    Ответ написан
    Комментировать
  • Почему не работает strcpy?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    ТС, Вы звезданулись что ли, весь исходник пихать в вопрос? Кому нафиг сдалась ваша лаба? Текста ошибки было бы достаточно. Сперли откуда-то исходник, даже не почитав, как пишутся программы на C.

    Добавьте в начало программы две строки
    #include <stdio.h>
    #include <string.h>


    и когда заработает (если конечно заработает) - попробуйте себе обьяснить, что Вы сделали. Честное слово, будет полезно, если Вы собираетесь стать программистом (ну а если учитесь, чтобы "прослушать" - можно и не делать, сдать лабу и забыть все нахрен)
    Ответ написан
    4 комментария
  • Как работает while ( !feof ( cfPtr ) )?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Фигово работает. Я помню этот кондовый пример с while(!feof()) - и помню, что он у меня как раз и не заработал. Что привело меня к быстрому-быстрому изучению прямого чтения-записи (open/read/close).
    Если же нужно работать именно потоковыми функциями - fgets() и прочие возвращают EOF в качестве признака конца файла.
    Ответ написан
    1 комментарий
  • Как записать данные в текстовый файл на C(си)?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Листинг кривой :) Где инклуды? :) Зачем там namespace - это что, плюса?

    man open
    man write
    man close

    выводить конечно же не через fprintf, а через write, размер берется как sizeof(struct vec) * 1000
    Ответ написан
    Комментировать
  • Имена массивов в си?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Здравствуйте, чем является имя массива в C?

    Ничем. "Имя массива" - это просто удобное название для тех, кто не одолел темы указателей. Те, кто эту тему одолел, таким вопросом уже не задаются, потому что статические массивы типа int[5] для них просто перестают существовать. "Имя массива" указывает на его первый элемент, но сделать с ним ничего нельзя. Точка. Не нравится - используйте динамические массивы.
    При создании многомерного массива (двух мерного в частности)

    "Двумерный (трех- , четырех-, n- мерный) массив" - это абстракция. В памяти данные идут последовательно, следовательно вся "мерность" массива - это автоматическое перемещение текущего указателя к некоей точке. Что опять нас возвращает к вопросу о статических и динамических массивах.

    Осваивайте указатели и все эти костыли отвалятся сами по себе.
    Ответ написан
    Комментировать
  • Как вывести символы из строки?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    man strlen (и даже неудобно такое писать - strlen() - это одна из первых строковых функций :) )
    man calloc

    Для перечисления нужно завести отдельные массивы и копировать туда символ если условие сработало. А потом этот массив просто вывести.

    Кроме того, статические массивы - зло, память надо брать динамически. Код я не привожу намеренно, потому что Вы учитесь и Ваше обучение и состоит в изучении того, какие есть строковые функции а не в копипастинге. Как основа эта программа годится. Но в ней нужно:
    - заменить статическую память на динамическую
    - после чтения строки проверить ее длину, если она > 20 - спросить заново, что нас естественно приводит к тому, что запрос будет делаться в бесконечном цикле
    - в разборочном if не только крутить нужные счетчики, но и копировать символ в соответствущий массив.
    - после окончания разбора вывести все отобранные массивы.
    Ответ написан
    Комментировать
  • Как скопировать определенную строчку из файла?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Поиском в текстовом массиве.
    Через stat() получить размер файла, через malloc() запросить память, через open() / read() / close() считать его в массив - а дальше тупо strnstr() :)
    Просто как полено.

    А когда нашел нужное место в массиве - тут уже с ним можно что хочешь делать - копировать, выводить...
    Ответ написан
    Комментировать
  • Код с условием выхода, но работает только 1 scanf(), почему?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Чтобы гарантированно забирать символ с потока, используйте getc() или getchar() вместо scanf().

    JFYI: Форматирование кода придумали не просто так, а чтобы глаза не ломать на таких вот "произведениях искуства".
    Ответ написан
    6 комментариев
  • Как считать из файла двоичные числа и перевести их в десятичные?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    - Открыть файл в двоичном режиме (это важно! иначе все поломается!), выделить под него память, считать файл, закрыть
    - наложить на него указатель на массив коротких целых
    - перебрать массив, найти минимумы, максимумы, это простейшие вещи, их полно в тырнете
    - вывести на экран

    Ничего сложного от слова совсем. На коленке пишется.
    Ответ написан
    Комментировать
  • Как передавать строки в поле структуры Си?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Гуглим односвязный список.

    Кстати, зачем списку связность? Для поиска? Тогда лучше двусвязный, вперед и назад, правда заполнение становится сложнее.
    И память брать не только для структуры, но и для поля данных. И чистить сразу, чтобы не вляпаться.
    #define MAXLEN 1024 // Задаемся максимальной длиной строки
    struct Node *head;
    
    if ((head = calloc(sizeof(struct Node) + MAXLEN,1)) == NULL)
      puts("Cannot alloc memory");
    
    head->str = head + sizeof(struct Node); // тут данные
    strncpy(head->str¸ name, strlen(name));

    Почему нельзя просто переадресовать name? Если оно из кучи, оно запросто будет переписано, лучше хранить отдельно. Тупо но надежно.

    UPD: Немного поправил код - переставил неверно поставленную скобку в calloc()
    Ответ написан
    3 комментария
  • Почему данный код не срабатывает?

    CityCat4
    @CityCat4
    Внимание! Изменился адрес почты!
    Потому что так нельзя.

    С - это не Perl, это низкоуровневый язык. Работая с массивами, нужно хорошо знать тему указателей, чтобы не задавать таких вопросов.
    Имя массива - это указатель на его первый элемент. То, что такая программа вообще собирается - это уступка ламерам, по идее тут ошибка должна выдаваться, чтобы давать по рукам сразу. В данном случае сравниваются два указателя, а они естественно разные.

    Строковые массивы можно сравнивать через strncmp()
    Числовые - перебором по значению
    Ответ написан
    Комментировать