ANSI C расщепляющая строка - PullRequest
1 голос
/ 20 апреля 2011

Привет! Я застрял в проблеме ANSI C , которая, на мой взгляд, должна быть довольно тривиальной (по крайней мере, на любом современном языке: /).

(временная) цель моего сценария - разделить строку (массив символов) из 6 символов («123: 45»), которая представляет метку времени минуты: секунды (для аудиофайлов, поэтому нормально иметь 120 минут) в минуты и секунды.

Я попробовал несколько подходов - общий с поиском «:» и жестко закодированный, просто разбивающий строку по индексам, но ни один из них, похоже, не работает.

void _splitstr ( char *instr, int index, char *outstr ) {
char temp[3]; 
int i; 
int strl = strlen ( instr );
if ( index == 0 ) {
    for ( i = 0; i < 3; ++i ) {
        if ( temp[i] != '\0' ) {
            temp[i] = instr[i];
        }
    }
} else if ( index == 1 ) {
    for ( i = 6; i > 3; i-- ) {
            temp[i] = instr[i];
        }
    }
strcpy ( outstr, temp );
}

Еще одна «забавная» вещь заключается в том, что длина строки символа [3] равна 6 или 9 и никогда не равна 3. Что с этим не так?

Ответы [ 7 ]

6 голосов
/ 20 апреля 2011

Как насчет использования sscanf().Как можно проще.

    char time[] = "123:45";
    int minutes, seconds;

    sscanf(time, "%d:%d", &minutes, &seconds);

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

Рабочий пример: http://ideone.com/vVoBI

1 голос
/ 20 апреля 2011

Как насчет ...

int seconds, minutes;
minutes = atoi(instr);
while(*instr != ':' && *++instr != '\0');
seconds = atoi(instr);

Должно быть довольно быстро.

0 голосов
/ 20 апреля 2011

Вот один из способов, я проигнорировал приведенный выше аргумент "index":

#include <stdio.h>
#include <string.h>

void _splitstr ( char *instr, char *outstr ) {
        char temp[10];
        char* end = strchr(instr, ':');
        int i = 0;

        if(end != 0) {
                while(instr != end)
                        temp[i++] = *instr++;
                temp[i] = '\0';
                strcpy(outstr, temp);
        } else {
                outstr = '\0';
        }
}
0 голосов
/ 20 апреля 2011

Это

char *mins, *secs;
mins = str;
while(*(++str) != ':');
str[0] = '\0';
secs = s + 1;
0 голосов
/ 20 апреля 2011

Вы не ставите завершающий нуль на вашей строке в temp [], поэтому, когда вы делаете strlen (temp), вы получаете доступ к произвольной памяти.

Используя ваши известные длины, вы можете использовать что-токак это:

char temp[4];
if (index==0)
{
  strncpy(temp, instr, 3);
  temp[3] = 0;
}
else if (index==1)
{
  strncpy(temp, instr+4, 2);
  temp[2] = 0;
}
strcpy(outstr, temp);

Но я предупреждаю, что я пропустил все виды проверки на допустимые длины в instr и outstr.

0 голосов
/ 20 апреля 2011

У вас есть в основном три варианта

  • изменение входной строки (не может быть строковым литералом)
  • копирование данных в выходные строки (входные данные могут быть литералами)
  • преобразование последовательности символов в числа

Изменение входной строки подразумевает преобразование "123:45" в "123\0" "45" со встроенным нулем.

Копирование данных подразумевает управление хранилищем дляcopy.

Преобразование последовательностей символов подразумевает использование, например, strtol.

0 голосов
/ 20 апреля 2011

вы можете попробовать что-то вроде этого:

void break_string(const char* input, char* hours, char* minutes)
{
    if(input == 0 || hours == 0 || minutes == 0)
        return;

    while(*input != ':')
        *hours++ = *input++;

    *hours = '\0';
    ++input;

    while(*minutes++ = *input++);

    return;
}

Вот та же функция, немного упрощенная:

void break_string(const char* input, char* hours, char* minutes)
{
    if(input == 0 || hours == 0 || minutes == 0)
        return;

    while(*input != ':')
    {
        *hours = *input;
        ++hours;
        ++input;
    }
    *hours = '\0';

    ++input; //ignore the ':' part
    while(*input)
    {
        *minutes = *input;
        ++minutes;
        ++input;
    }
    *minutes = '\0';

    return;
}

int main()
{
    char* test = "123:45";
    char* minutes   = malloc( sizeof(char) * 12 );
    char* hours     = malloc( sizeof(char) * 12 );
    break_string( test , hours , minutes );
    printf("%s , %s \n" , hours , minutes ); 
    //...
    free( minutes );
    free( hours ) ;
}
...