Use strtok like the following... arrayOfString will have list of strings.

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

int main()
{
   char str[80] = "apples, pears, oranges,";
   char* arrayOfString[3];
   const char s[2] = ", ";
   char *token;
   int i=0;
   /* get the first token */
   token = strtok(str, s);

   /* walk through other tokens */
   while( token != NULL ) 
   {
      arrayOfString[i] = token;
      token = strtok(NULL, s);
      i++;
   }

   for(i=0;i<3;i++)
    printf("%s\n", arrayOfString[i]);

   return(0);
}
Answer from sabbir on Stack Overflow
Top answer
1 of 2
1

Your data field only holds one char now. It needs to have room for at least the typical value, like 02/19/18.

Use char[10] for example (if you know for sure that it can never be longer than 9 characters).

I think the compiler ought to have warned against your fscanf call.

2 of 2
0

Your fscanf() calls are off: When you make this call

fscanf(csv, "%s[^,]", v[i].data);

fscanf() will first parse a string of non-whitespace characters until it finds a whitespace character (the %s conversion), so "02/20/18,11403.7" gets written to your array, and your buffer will overflow. After that, you are in undefined behavior territory, and anything could happen. The [^,] conversion won't even be reached before you get UB.

Of course, you can simply fix this by dropping the %s from your format string, but I think, what you really want to do, is to just parse all the numbers as numbers:

int month, day, year;
double value;
int conversionCount = fscanf(csv, "%d/%d/%d,%lf\n", &month, &day, &year, &value);
if(conversionCount != 4) {
    handleError();
}

Do not forget to check the result of fscanf() as it's the only way to know whether parsing completed successfully. I have added \n at the end of the format string, which will gobble up any whitespace following the float value, including the newline character. This allows you to perform your conversions one line at a time with a single fscanf() in a simple loop, without any need to call fseek(). Just keep parsing lines until an fscanf() call returns something other than the number of conversions you expect.

🌐
Stack Overflow
stackoverflow.com › questions › 69837167 › converting-a-comma-separated-string-to-array
c - Converting a comma separated string to array - Stack Overflow
If you don't see an error message for s1[k] = strdup(mchar); then change your compiler settings, as you are wasting time trying to run incorrect code ... Hi all, sorry there was typo in the define, also @klutt I have made my code reproducible ...
🌐
Make Community
community.make.com › questions
Convert a String containing commas as separators into an Array - Questions - Make Community
January 31, 2023 - I have a string of text “01pdf1,01sb1”. The comma in the text is a separator between two elements: “01pdf1” and “01sb1”. I want to conduct a series of operations for each element. In order to do this, I think I should use the iterator module. In order to use the iterator, I need to convert this original text string into an array so that it can deal with each element separately.
🌐
Reddit
reddit.com › r/c_programming › how do i convert a comma separated text file to a char array?
r/C_Programming on Reddit: How do I convert a comma separated text file to a char array?
April 13, 2022 -

I'm trying to do some advent of code challenges with C but I can't figure out the proper way to convert my input from a text file to an array. (Of course I could just copy the input directly into my C-file to use as an array but I want to understand how I can get it from a text file to an array). Also I want to get the length of that array.

My input looks like this: 3,5,1,2,5,4,1,5,1,2,5, ...

Here's what I already have

 int main() {
    FILE *fp = fopen("../input.txt", "r");
    assert(NULL != fp);

    int length = 0;
    char charArray[] = {};
    while (!feof(fp)) {
        char ch = fgetc(fp);
        if (isdigit(ch)) {
            length++;
            // push to charArray?
        }
    };
    fclose(fp);
    for (int i = 0; i < length; ++i) {
        printf("%d,",charArray[i]);
    }
    printf("%d\n", length);
    return 0;
}
🌐
Reddit
reddit.com › r/programming › using c, convert a dynamic int array to a comma-separated string as cleanly as possible
r/programming on Reddit: Using C, convert a dynamic int array to a comma-separated string as cleanly as possible
November 16, 2009 - Actually you can print into a string with snprintf (avoid sprintf, it allows buffer overruns too easily). But I'm really wondering why you don't just iterate over the array and log the elements with commas in between, rather than munge everything into a string and log that.
Find elsewhere
🌐
Codemia
codemia.io › home › knowledge hub › how can i convert a comma-separated string to an array?
How can I convert a comma-separated string to an array? | Codemia
January 8, 2025 - IntroductionThe basic answer is to split the string on commas. The real work starts after that, because production input often contains spaces, empty items,...
🌐
GeeksforGeeks
geeksforgeeks.org › convert-comma-separated-string-to-array-using-javascript
JavaScript – Convert Comma Separated String To Array | GeeksforGeeks
November 26, 2024 - The split() method is the simplest and most commonly used way to convert a comma-separated string into an array. It splits a string into an array based on a specified character, such as a comma.
Top answer
1 of 4
3

You have several issues to work through to convert your function from simply printing the separated strings to stdout to saving the separated strings in ArrayOfString. Before getting to the changes, let's avoid using magic numbers in your code.

char ArrayOfString[10][5];

In ArrayOfString above, 10 and 5 are magic numbers. They are hardcoded values that will govern everything from the declaration size to required validation checks to protect your array bounds. Instead of hardcoding values, if you need a constant, define one (or more), e.g.

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

#define ROW 10
#define COL  5

char ArrayOfString[ROW][COL];

Now on to separating your string into tokens. The C-library provides a function specifically tailored to separating delimited strings into tokens. Conveniently named strtok. The only caveat to know about strtok is that it modifies the string, so if you need to preserve the original, make a copy first.

To use strtok (string, delims) to separate string into tokens at delims, your first call to strtok takes string as the 1st parameter. All subsequent calls use NULL in its place. You can either make an initial call to strtok and then use a while loop to complete the process, or a for loop is tailor made for handling the initial call, as well as all subsequent calls with NULL.

For example your function utilizing strtok to separate string into tokens and providing a size_t return of the number of tokens copied to ArrayOfString could be similar to:

char ArrayOfString[ROW][COL];

size_t vSeparateSringByComma (char* string)
{
    const char *delims = ",\n";
    char *s = string;
    size_t n = 0, len;

    for (s = strtok (s, delims); s && n < ROW; s = strtok (NULL, delims))
        if ((len = strlen (s)) < COL)
            strcpy (ArrayOfString[n++], s);
        else
            fprintf (stderr, "error: '%s' exceeds COL - 1 chars.\n", s);

    return n;
}

(note: how your array bounds are protected both by the check with n < ROW and each row array bound is protected with (len = strlen (s)) < COL before the copy to ArrayOfString[n++] is made)

(also note: how by not using magic numbers, if you change the ROW or COL size in the future, only the constants need changing and the change is automatically incorporated throughout your code by virtue of using constants)

Your example program would then be:

int main(void) {

    char string[] = "$,0,3,307,183,18,5,119,1,#";
    size_t n = vSeparateSringByComma (string);

    for (size_t i = 0; i < n; i++)
        printf ("ArrayOfString[%zu] : '%s'\n", i, ArrayOfString[i]);
}

Example Use/Output

$ ./bin/arrayofstrings
ArrayOfString[0] : '$'
ArrayOfString[1] : '0'
ArrayOfString[2] : '3'
ArrayOfString[3] : '307'
ArrayOfString[4] : '183'
ArrayOfString[5] : '18'
ArrayOfString[6] : '5'
ArrayOfString[7] : '119'
ArrayOfString[8] : '1'
ArrayOfString[9] : '#'

Using strcspn and strspn Instead of strtok

As discussed in the comments, using strcspn to report the number of sequential characters not containing a delimiter allowing you to determined the length of each field. You then need to skip over the delimiters (which in many cases can be made up of more than one delimiter (e.g. $, 0, 3, ...).

While strtok considers multiple sequential delimiters a single delimiter, you would need a similar way to skip over the intervening delimiters to position your self to read the next field. strspn will work nicely using the same delims, but this time reporting the number of characters made up of only characters within delims (allowing you to add that to your len and then len to s to position yourself for the next read)

A short variation using strcspn and strspn could be:

size_t vSeperateSringByComma (char* string)
{
    const char *delims = ",\n";
    char *s = string;
    size_t n = 0, len;

    while ((len = strcspn (s, delims))) {   /* number of non-delim chars */
        if (len < COL) {                    /* validate it will fit */
            memcpy (ArrayOfString[n], s, len);  /* copy len chars */
            ArrayOfString[n++][len] = 0;    /* nul terminate at len */
        }
        else
            fprintf (stderr, "error: '%s' exceeds COL - 1 chars.\n", s);

        len += strspn (s + len, delims);    /* scan past delimiter(s) */
        s += len;               /* update s to beginning of next field */
    }

    return n;
}

(the output is the same)

Look things over and let me know if you have further questions.

2 of 4
1

replace

printf("%.*s\n", (int)field_len, s);

with

sprintf(ArrayOfString[i],"%.*s\n", (int)field_len, s);

then you can print the 4 first elements with

for( i=0 ; i<4 ; i++)
   printf("%s" , ArrayOfString[i] );
Top answer
1 of 3
1
One would 1st call the string's · split · method: · var list = ' item 1, item 2 , ,item 3 '; · var array = list · .split(','); · gs.debug('\n[' + array.join(']\n[') + ']'); · This prints: · *** Script: [DEBUG] · [ item 1] · [ item 2 ] · [ ] · [item 3 ] · Pretty all over the place. · For better result - where the leading and trailing spaces are removed - one would use · trim · before splitting: · var list = ' item 1, item 2 , ,item 3 '; · var array = list · .trim() · .split(','); · gs.debug('\n[' + array.join(']\n[') + ']'); · *** Script: [DEBUG] · [item 1] · [ item 2 ] · [ ] · [item 3] · Really only slightly better - only the 1st and the last items look good - and half of both only by chance (the one who entered the list did not add extra spaces after the last item and before the 1st one). · To take care of all extra spaces for all items that could exist due to sloppy fellow programmers composing the list or faulty data entry, one would switch the splitter to · RegExp · : · var list = ' item 1, item 2 , ,item 3 '; · var array = list · .trim() · .split(/\s*,\s*/g); · gs.debug('\n[' + array.join(']\n[') + ']'); · *** Script: [DEBUG] · [item 1] · [item 2] · [] · [item 3] · A lot better, almost there, just one problem remains: the 3rd item which is empty. · To take care of that problem one might · filter · the resulting array: · var list = ' item 1, item 2 , ,item 3 '; · var array = list · .trim() · .split(/\s*,\s*/g) · .filter(retainNotEmpty); · function retainNotEmpty (item) { · return '' != item; · } · gs.debug('\n[' + array.join(']\n[') + ']');​ · *** Script: [DEBUG] · [item 1] · [item 2] · [item 3] · Just about what one desires. · Filtering will also fix the issue of empty string ending up (not in a 0 length array, but) in an array with one item when split.
2 of 3
0
Hi @hardikbendre , · Please use the below to convert comma separated value into an array: · // dec stores the comma separated values · var dec = "service,now,community" · var colSplit = dec.split(","); · var arr=[]; · for(i=0;i
🌐
Stack Overflow
stackoverflow.com › questions › 48302324 › how-to-put-string-elements-separated-by-commas-into-an-int-array
c++ - How to put string elements separated by commas into an int array? - Stack Overflow
Please decide what you want, an int array as the title says or a string array as implied elsewhere. n.m.is-an-unemployed-ai-agent – n.m.is-an-unemployed-ai-agent · 2018-01-17 13:59:18 +00:00 Commented Jan 17, 2018 at 13:59 ... #include <algorithm> #include <iostream> #include <sstream> #include <string> #include <vector> std::vector<int> convertToIntArray(std::string input) { std::replace(input.begin(), input.end(), ',', ' '); std::istringstream stringReader{ input }; std::vector<int> result; int number; while (stringReader >> number) { result.push_back(number); } return result; } int main() { std::string testString = "5,6,13,4,14,22"; std::vector<int> newArray = convertToIntArray(testString); for (int i = 0; i < newArray.size(); ++i) { std::cout << newArray[i] << " "; } }
🌐
C# Corner
c-sharpcorner.com › article › convert-a-comma-delimited-string-to-an-array-in-C-Sharp
Convert a Comma Delimited String to an Array in C#
May 15, 2012 - String.Join method comes handy, when we need to convert an array into a comma delimited strings or vice versa. The folloing code snippet shows how to convert an array to a comma delimited string.
🌐
TutorialsPoint
tutorialspoint.com › How-to-convert-comma-seperated-java-string-to-an-array
How to convert comma seperated java string to an array.
Yes, use String.split() method to do it. See the example below − · Get certified by completing the course
Top answer
1 of 3
7
  • sizeof(char) by definition is 1. tmp += l + 1; would be as good.

  • I don't see a need to special case l == 0.

  • You don't have to initialize l in a loop header: it is immediately reassigned.

  • gcc complains about precision specifier in printf("\"%.*s\"\n", l, tmp) being size_t; unfortunately, cast is unavoidable.

  • I don't see a need for 2 separate loops. A single

    char * tmp = (char *)str;
    do {
        int l = strcspn (tmp, tok);
        printf("\"%.*s\"\n", l, tmp);
        tmp += l + 1;
    } while (tmp[-1]);
    return 0;
    

    works equally well.

2 of 3
5

Solution

As @vnp noted, the "correct" solution is much simpler. I would make a few changes and write it as:

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

int main() {
    const char string[] = "comma separated,input,,,some fields,,empty";
    const char delims[] = ",";

    const char *s = string;
    do {
        size_t field_len = strcspn(s, delims);
        printf("\"%.*s\"\n", (int)field_len, s);
        s += field_len;
    } while (*s++);
}

Notable changes include:

  • Friendlier variable names
  • Don't cast away the const
  • Ensure that printf() gets an int for the field width specifier
  • Smarter loop termination test (check for the NUL terminator then increment the pointer)

Nasty loop

Your original solution contains a loop that is particularly convoluted:

char * tmp = (char *)str;
size_t count;
for (count=0; tmp[count]; tmp[count] == tok[0] ? count++ : * tmp++) {
    //Empty loop body.
}
tmp = (char *)str;

As discussed previously,

  • This loop, whose goal is to set count to the number of commas, turns out to be completely unnecessary.
  • Casting away const is bad.

In addition,

  • The loop manipulates both count and tmp, which makes it very confusing. When the loop terminates, tmp points to count bytes before the end of the string. That's just weird!

    The non-weird version would be:

    int count = 0;
    for (const char *tmp = str; *tmp; tmp++) {
        if (*tmp == tok[0]) count++;
    }
    

    Note the very conventional loop header: start at the beginning of str, walk one byte at a time until NUL is reached. Also, tmp is truly temporary, and falls out of scope after the loop, so you don't have to worry about resetting it. The loop body is straightforward as well: increment count for each comma.

  • * tmp++ is a superfluous pointer dereference that just adds confusion and noise.