Сплит строка с разделителями в C - PullRequest
142 голосов
/ 09 февраля 2012

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

char* str = "JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC";
str_split(str,',');

Ответы [ 25 ]

0 голосов
/ 20 июля 2017

Еще один ответ (это было перенесено сюда из здесь ):

Попробуйте использовать функцию strtok:

см. Подробности по этой теме здесь или здесь

Проблема здесь в том, что вы должны немедленно обработать words.Если вы хотите сохранить его в массиве, вы должны выделить correct size для него, который неизвестен.

Так, например:

char **Split(char *in_text, char *in_sep)
{
    char **ret = NULL;
    int count = 0;
    char *tmp = strdup(in_text);
    char *pos = tmp;

    // This is the pass ONE: we count 
    while ((pos = strtok(pos, in_sep)) != NULL)
    {
        count++;
        pos = NULL;
    }

    // NOTE: the function strtok changes the content of the string! So we free and duplicate it again! 
    free(tmp);
    pos = tmp = strdup(in_text);

    // We create a NULL terminated array hence the +1
    ret = calloc(count+1, sizeof(char*));
    // TODO: You have to test the `ret` for NULL here

    // This is the pass TWO: we store
    count = 0;
    while ((pos = strtok(pos, in_sep)) != NULL)
    {
        ret[count] = strdup(pos);
        count++;
        pos = NULL;
    }
    free(tmp);

    return count;
}

// Use this to free
void Free_Array(char** in_array)
{
    char *pos = in_array;

    while (pos[0] != NULL)
    {
        free(pos[0]);
        pos++;

    }

    free(in_array);

}

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

Примечание 2 : Вы можете использовать другую реализацию strtok, причины которой указаны в отдельных постах.

Вы можете использовать это как:

int main(void)
{
  char **array = Split("Hello World!", " ");
  // Now you have the array
  // ...

  // Then free the memory
  Free_Array(array);
  array = NULL;
  return 0;
}

(я не проверял его, поэтому, пожалуйста, дайте мне знать, если он не работает!)

0 голосов
/ 10 мая 2017

Для: Hassan A. El-Seoudy

Ваш билет закрыт, поэтому я не могу ответить на него ^^ '.Но вы можете попробовать это:

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

int     countChar(char *str)
{
  int   count;
  int   i;

  i = 0;
  count = 0;
  while (str[i] != '=') // our delimiter character
    {
      i++;
      count++;
    }

  return (count);
}

void    split(char *str)
{
  int   i;
  int   j;
  int   count;
  int   restCount;
  char  *str1;
  char  *str2;

  i = 0;
  j = 0;
  count = countChar(str) - 1; // we have our str1 lenght, -1 for the ' '
  restCount = (strlen(str) - count) -1; // we have our str2 legnht, -1 for the ' '
  str1 = malloc(sizeof(char) * count);
  str2 = malloc(sizeof(char) * restCount);

  while(i < count)
    {
      str1[i] = str[i++];
    }
  i = i + 2; // to jump directly to the first char of our str2 (no ' = ')
  while (str[i])
    {
      str2[j++] = str[i++];
    }
  printf("str1 = %s, str2 = %s\n", str1, str2);
}

int     main()
{
  char  *str = "Xo = 100k";

  split(str);

  return (0);
}'
0 голосов
/ 14 января 2017

Это может решить вашу цель

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

int main()
{
    int i = 0,j = 0,k = 0;
    char name[] = "jrSmith-Rock";
    int length = strlen(name);
    char store[100][100];
    for(i = 0, j = 0,k = 0; i < length;) {
        if((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z')) {
            store[j][k] = name[i];
            k++;
            i++;
        }
        else{
            while(! isalpha(name[i])) {
                i++;
            }
            j++;
            k = 0;
        }
    }

    for(i = 0; i <= j; i++) {
        printf("%s\n", store[i]);
    }
    return 0;
}

Вывод:

jrSmith
Rock
0 голосов
/ 23 сентября 2016

Есть некоторые проблемы со strtok () , перечисленные здесь: http://benpfaff.org/writings/clc/strtok.html

Следовательно, лучше избегать strtok .

Теперь рассмотрим строку, содержащую пустое поле, следующим образом:

char myCSVString[101] = "-1.4,2.6,,-0.24,1.26"; // specify input here

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

int strCSV2Float(float *strFloatArray , char *myCSVStringing , char delim);

Мы указали разделитель здесь как запятую. Работает с другими односимвольными разделителями.

Ниже вы найдете Использование :

#include <stdio.h>
#include <stdlib.h>



int strCSV2Float(float *strFloatArray , char *myCSVStringing , char delim);

  void main()
 {

    char myCSVString[101] = "-1.4,2.6,,-0.24,1.26"; // specify input here
    float floatArr[10]; // specify size of float array here 
    int totalValues = 0;
    char myDelim = ','; // specify delimiter here 

    printf("myCSVString == %s \n",&myCSVString[0]);

    totalValues = strCSV2Float(&floatArr[0] , &myCSVString[0], myDelim); // call the function here 

    int floatValueCount = 0;

    for (floatValueCount = 0 ; floatValueCount < totalValues ; floatValueCount++)
    {

      printf("floatArr[%d] = %f\n",floatValueCount , floatArr[floatValueCount]);

    }

 }




int strCSV2Float(float *strFloatArray , char *myCSVStringing , char delim)
{

int strLen = 0;
int commaCount =0; // count the number of commas
int commaCountOld =0; // count the number of commas
int wordEndChar = 0;
int wordStartChar = -1;
int wordLength =0;


   for(strLen=0; myCSVStringing[strLen] != '\0'; strLen++) // first get the string length
   {

       if ( (myCSVStringing[strLen] == delim)  || ( myCSVStringing[strLen+1] == '\0' ))
        {
           commaCount++;
           wordEndChar = strLen;
        }
       if ( (commaCount - commaCountOld) > 0 )
        {
          int aIter =0;
          wordLength = (wordEndChar - wordStartChar);
          char word[55] = "";
          for (aIter = 0;  aIter < wordLength; aIter++)
          {
            word[aIter] = myCSVStringing[strLen-wordLength+aIter+1];
          }

          if (word[aIter-1] == delim) 
           word[aIter-1] = '\0';

          //  printf("\n");
          word[wordLength] = '\0';
          strFloatArray[commaCount-1] = atof(&word[0]);

          wordLength = 0;
          wordStartChar = wordEndChar;
          commaCountOld = commaCount;

        }  
  }

  return commaCount;

}

Вывод какследует:

myCSVString == -1.4,2.6,,-0.24,1.26 
floatArr[0] = -1.400000
floatArr[1] = 2.600000
floatArr[2] = 0.000000
floatArr[3] = -0.240000
floatArr[4] = 1.260000
0 голосов
/ 23 февраля 2016

Если вы хотите использовать внешнюю библиотеку, я не могу рекомендовать bstrlib.Это требует немного дополнительной настройки, но проще в долгосрочной перспективе.

Например, разделив строку ниже, сначала создается bstring с вызовом bfromcstr().(A bstring - это обертка вокруг буфера символов).Затем разделите строку на запятые, сохранив результат в struct bstrList, который имеет поля qty и массив entry, который является массивом bstring s.множество других функций для работы bstring s

Easy as pie ...

#include "bstrlib.h"
#include <stdio.h>
int main() {
  int i;
  char *tmp = "Hello,World,sak";
  bstring bstr = bfromcstr(tmp);
  struct bstrList *blist = bsplit(bstr, ',');
  printf("num %d\n", blist->qty);
  for(i=0;i<blist->qty;i++) {
    printf("%d: %s\n", i, bstr2cstr(blist->entry[i], '_'));
  }

}
...