Вам нужно решить несколько проблем, чтобы преобразовать вашу функцию от простой печати разделенных строк в stdout
до сохранения разделенных строк в ArrayOfString
.Прежде чем перейти к изменениям, давайте не будем использовать магические числа в вашем коде.
char ArrayOfString[10][5];
В ArrayOfString
выше 10
и 5
являются магическими числами .Это жестко закодированные значения, которые будут регулировать все от размера объявления до необходимых проверок правильности, чтобы защитить границы вашего массива.Вместо значений жесткого кодирования, если вам нужна константа, определите одну (или более), например,
#include <stdio.h>
#include <string.h>
#define ROW 10
#define COL 5
char ArrayOfString[ROW][COL];
Теперь разделите вашу строку на токены .Библиотека C предоставляет функцию, специально предназначенную для разделения строк с разделителями на токены.Удобно названный strtok
.Единственное предостережение, которое нужно знать о strtok
, - это то, что он изменяет строку, поэтому, если вам нужно сохранить оригинал, сначала сделайте копию.
Чтобы использовать strtok (string, delims)
для разделения string
на токены в delims
, ваш первый вызов strtok
принимает string
в качестве 1-го параметра.Все последующие звонки используют NULL
на своем месте.Вы можете либо сделать первоначальный вызов strtok
, а затем использовать цикл while для завершения процесса, либо цикл for
предназначен для обработки начального вызова, а также всех последующих вызовов с NULL
.
Например, ваша функция, использующая strtok
для разделения string
на токены и обеспечивающая size_t
возврат числа токенов, скопированных в ArrayOfString
, может быть похожа на:
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;
}
( примечание: как границы вашего массива защищены как проверкой с n < ROW
, так и с каждой границей массива строк, защищенной (len = strlen (s)) < COL
до копирования в ArrayOfString[n++]
)
( также обратите внимание: как, если не использовать магические числа , если в будущем вы измените размер ROW
или COL
, нужно будет изменить только константы, и это изменение будет автоматически включеново всем вашем коде благодаря использованию констант)
Ваш пример программы будет:
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]);
}
Пример использования / Вывод
$ ./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] : '#'
Использование strcspn
и strspn
вместо strtok
Как обсуждалось в комментариях, используйте strcspn
, чтобы сообщить количество последовательных символов, не содержащих разделитель, позволяющий вам определять длину каждого поля.Затем вам нужно пропустить разделители (которые во многих случаях могут состоять из нескольких разделителей (например, $, 0, 3, ...
).
Хотя strtok
считает несколько последовательных разделителей одним разделителем, вам потребуетсяаналогичный способ пропустить промежуточные разделители, чтобы расположить себя для чтения следующего поля. strspn
будет работать хорошо, используя тот же delims
, но на этот раз сообщая о количестве символов, состоящих только из символов в delims
(позволяя вам добавить это к вашим len
, а затем len
к s
, чтобы подготовиться к следующему чтению)
Короткий вариант с использованием strcspn
и strspn
может быть:
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;
}
(результат тот же)
Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы.