Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа со строками в С

32K
18 декабря 2009 года
xface
43 / / 07.11.2009
Привет. Есть задачка, нужно сделать прогу которая бы приводила подобные в многочлене произвольного вида. Например: 3x^2+4x^2+2x+3, ответ: 7x^2+2x+3. Вопрос, как можно узнать значения при коэффициентах х? Функция strchr(), не помогает. Как можно это реализовать или может есть другие простые фукнции, которые позволяют копировать из строки n символов начиная с позиции m?
29K
18 декабря 2009 года
Ander Skirnir
109 / / 08.06.2009
strchr - возвращает указатель на первое вхождение символа в строку, для поиска же подстроки в строке, используйте strstr.

Для преобразования строки в int - atoi.
Для копирования n символов одной строки в другую - strncpy.

Так как многочлен у Вас произвольного вида, наверное, лучше всего будет написать-таки парсер, который будет последовательно пробегать строку и сохранять лексемы в удобной структуре данных, а затем производить их обработку.

Код:
// перечисление типов лексемы
enum PType
{
    PType_Int,  // коеффициенты и степени
    PType_Var, // имена переменных
    PType_Op  // знаки операций
}

// структура для хранения лексемы
struct ParseResult
{
    PType type;

    union
    {
        char* sval;
        int ival;
    }
        value;
}

// собственно, парсинг
ParseResult ParseToken (char *str) { ... }


Как это будет работать:
Допустим, на вход даётся строка "5x^66+22", тогда при первом вызове ParseToken, она вернёт структуру ParseResult с {type = PType_Int, value.ival = 5}, при втором: {type = PType_Var, value.sval = "x"}, при третьем: {type = PType_Op, value.sval = "^"} и т.д.

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

Если бы у меня была куча времени, я бы Вам набросал пример самой функции, но его, к сожалению нет.
32K
18 декабря 2009 года
xface
43 / / 07.11.2009
Вобще я хотел реализовать и уже реализовал следующим образом:

 
Код:
char Text[100];
char z[1];

 for (int i = 0; i < strlen(Text); i++)
   if (Text == 'x')  // Если нашли x, то
     z[0] = Text[i - 1]; // Копируем значение левее х.


Но вот тут возникает проблема, скопировать то мы можем только 1 символ, т.е если стоит 25x, то копируется только 5.

Нет ли функции типа Copy, как в паскале?

Я хотел бы сделать так:

Находим х, копируем все символы левее его до начала строки, затем смотрим если у нас есть знак степени ^, если есть, то копируем все символы до знакак + или - ну и так далее.
29K
18 декабря 2009 года
Ander Skirnir
109 / / 08.06.2009
>> скопировать то мы можем только 1 символ
Ну я ж в прошлом посте писал:
char *strncpy(s, ct, n) - копирует не более n символов из строки ct в строку s.

Т.е. Вы можете в цикле двигаться от x влево до тех пор, пока не встретите не-цифру или не попадёте в нулевую позицию строки и затем копировать подстроку, начинающуюся с этой позиции и кол-вом символов, равным кол-ву шагов от x.
32K
19 декабря 2009 года
xface
43 / / 07.11.2009
А как можно скопировать n символов не с начала строки, а с позиции x?
29K
19 декабря 2009 года
Ander Skirnir
109 / / 08.06.2009
Ну так s, ct - указатели (char*). Если s указывает на начало строки, то s+k - на подстроку, начинающуюся с k-го символа включительно. Арифметика указателей.
32K
19 декабря 2009 года
xface
43 / / 07.11.2009
Цитата: Ander Skirnir
Ну так s, ct - указатели (char*). Если s указывает на начало строки, то s+k - на подстроку, начинающуюся с k-го символа включительно. Арифметика указателей.



А можно примерчик, а то я чета ваще запутался(

29K
19 декабря 2009 года
Ander Skirnir
109 / / 08.06.2009
 
Код:
int main (void)
{
   char *str1 = "glass",
        *str2 = malloc(4); // 'a', 's', 's', '\0'

   strncpy(str2, str1+2, 3);

   printf(str1); // glass
   printf(str2); // ass
}


Если бы строка str1 была длинее, во вторую всё-равно скопировало бы только "ass", т.к. n = 3.
32K
19 декабря 2009 года
xface
43 / / 07.11.2009
Код:
int main()
{
    char S[255];
    char S2[255];
    char *st;
    char *st2;
    int i;


       scanf("%s", S);

      for (i = 0; i < strlen(S); i++)
      {
       if ((S == 'x') && (i > 0))
       {
        strncpy(S2, S, i);
        printf("%s %d", S2, i);
       }

       if (S == '^')
       {
           st = S;
            strncpy(st, st2+2, 1);
             printf("\n%s", st);
       }

      }

}


Накидал код, вот элемент левее х находится, а правее ^ нет. Да вообще для сравнения я использую просто строку, а вот для копирования указатель. Только вообще ни черта не выходит. Ваще строки в С дерьмо еще то.
29K
19 декабря 2009 года
Ander Skirnir
109 / / 08.06.2009
>> для сравнения я использую просто строку, а вот для копирования указатель
в Си нет строк

>>строки в С дерьмо еще то
см. выше

Строки эмулируются массивами символов и указателями.

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

И еще: в последнем Вашем посте коеффициент при x находит неправильно: у Вас копирование начинается с начала строки, а нужно начинать с места, где начинается сам коеффициент.

Вот пример:
Код:
#include <stdio.h>

// byte в коде будет заменяться на unsigned char - число в диапазоне [0; 255]
typedef unsigned char byte;

int parse_koef (char *str, byte spos)
{
    char sk [8];

    byte i, k = 0,
         j = spos ? spos - 1 : 0; // если spos > 0, то j = spos - 1, иначе j = 0
         
    for (i = spos ? spos : 1; i < strlen(str); ++j, ++i)
        if (str == 'x')
        {
           
            while (isdigit(str[j])) // пока str[j] - десятичная цифра
            {            
                if (j == 0) break;
                ++k, --j;            
            }        
               
            strncpy(sk, str + i - k, k);
            sk[k] = '\0';
           
            break;
        }
       
    return atoi(sk);
}

int main()
{
    char *s = "122 + 52 + 43 + 6522x + 235x";

    int k1 = parse_koef(s, 0);
    printf("k1 = %d\n", k1);

    int k2 = parse_koef(s, 22);
    printf("k2 = %d\n", k2);    
}


Здесь parse_koef находит для заданной строки коеффициент при первом х, встречающемся после заданной позиции.

k1 = 6522
k2 = 235
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог