2013-03-24 5 views
-1

Я хочу сделать функцию, которая, данная строка символов, содержащая (без знака) целочисленных значений, разделенных пробелами, дает мне количество значений в строке:сосчитать, сколько целых значений, разделенных пробелами в данной строке

int conta_coords(char *args) { 
    char *pal; 
    int k=0; 
    pal = strtok (args," "); 
    while (pal != NULL) 
    { 
     k++; 
     pal =strtok (NULL," "); 
    } 
    return k; 
} 

Эта функция не даст мне правильный номер. Может кто-нибудь мне помочь?

+0

Не могли бы вы предоставить вызов? – md5

+0

В дополнение к тому, что просил @ Кириленко, какое значение вы передаете как 'args' и какова ваша функция? – adamdunson

ответ

1

Каким образом он не даст вам правильный номер? Вот ваш код, встроенный в SSCCE (Short, Self-Contained, Correct Example).

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

extern int conta_coords(char *str); 

int conta_coords(char *args) { 
    char *pal; 
    int k=0; 
    pal = strtok (args," "); 
    while (pal != NULL) 
    { 
    k++; 
     pal =strtok (NULL," "); 
    } 
    return k; 
} 

int main(void) 
{ 
    char data[] = "1 23 456 7890 12345"; 
    printf("Data: %s\n", data); 
    printf("Number: %d\n", conta_coords(data)); 
    printf("Data split: %s\n", data); 
    return 0; 
} 

Выход:

$ ./cntnum 
Data: 1 23 456 7890 12345 
Number: 5 
Data split: 1 
$ 

Это выглядит правильно для меня. Обратите внимание, что исходная строка была разбита на части. Кроме того, если бы я передал строку только для чтения (строковый литерал), я мог бы получить разные результаты, потому что strtok() изменяет данные, на которых он работает, но строковые литералы не всегда изменяемы (и вы можете получить базовую дамп из пытаясь изменить его). Например:

printf("Number: %d\n", conta_coords(" 1  23 45 67 99 ")); 

Это дает мне «ошибку шины» (и даст дамп ядра, если они не будут отключены).

Вот альтернативная реализация, которая работает на постоянных строках, не изменяя найденную строку на всех, используя много-недооценен стандартных функций C89 strspn() и strcspn():

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

extern int conta_coords(const char *str); 

int conta_coords(const char *str) 
{ 
    const char digits[] = ""; 
    const char *ptr = str; 
    int k = 0; 
    int n = strcspn(ptr, digits); 
    while (ptr[n] != '\0') 
    { 
     ptr += n; 
     n = strspn(ptr, digits); 
     if (n > 0) 
      k++; 
     ptr += n; 
     n = strcspn(ptr, digits); 
    } 
    return k; 
} 

int main(void) 
{ 
    char data[] = "1 23 456 7890 12345"; 
    printf("Data: %s\n", data); 
    printf("Number: %d\n", conta_coords(data)); 
    printf("Data unsplit: %s\n", data); 
    printf("Number: %d\n", conta_coords(" 1  23 45 67 99 ")); 
    return 0; 
} 

Выход:

Data: 1 23 456 7890 12345 
Number: 5 
Data unsplit: 1 23 456 7890 12345 
Number: 5 

Обратите внимание, что одна законная критика в этом заключается в том, что она не требует, чтобы целые числа были разделены пробелами (поэтому более точная характеристика этого «подсчитывает количество последовательностей одного или нескольких смежных digi ts (разделенные одной или несколькими цифрами) отображаются в заданной строке '). Но исходный код также может быть подвергнут критике по аналогичным причинам: он подсчитывает количество последовательностей последовательных не-пробелов, разделенных одной или несколькими пробелами, появляется в данной строке. Вы можете уточнить реализацию, но будьте осторожны с тем, как вы обрабатываете ошибочно отформатированные данные и сообщаете о проблемах.

1

Нечто подобное:

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

bool is_stringified_num(const char *str, const size_t size) 
{ 
    int n = 0; 
    while(n < size && isdigit(str[n++])); 

    return n == size; 
} 

int str_numbers_count(char *str) 
{ 
    int numbers_count = 0; 
    char *prev_pos = str; 
    char *pos = strchr(str, ' '); 

    while(pos) 
    { 
     if (is_stringified_num(prev_pos, pos - prev_pos)) ++numbers_count ; 
     prev_pos = ++pos; 
     pos = strchr(pos, ' '); 
    } 

    if (is_stringified_num(prev_pos, strlen(str) - (prev_pos - str))) ++numbers_count ; 

    return numbers_count ; 
} 

int main(int argc, char *argv[]) 
{ 
    char str[] = "1 23 456 7890 12345"; 
    printf("%s contains %d numbers\n", str, str_numbers_count(str)); 

    return 0; 
} 

Ideone компилирует хорошо и выходы:

1 23 456 7890 12345 contains 5 numbers 
+0

Почему бы не добавить тестовый код? Это не должно быть сложным или тщательным; достаточно, чтобы показать, что он делает то, что вы ожидаете от некоторых выборочных данных. –

+0

@JonathanLeffler, я обязательно – maverik

Смежные вопросы