#include <stddef.h>
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define ARRAY_SSIZE(arr) ((ptrdiff_t)ARRAY_SIZE(arr))
int main (void)
{
FILE *fp;
char buff[BUFSIZ];
char *s;
ptrdiff_t len;
char str[10][10][10];
int n;
fp = fopen("./data.txt", "r");
memset(str, 0, sizeof(str));
for (ptrdiff_t i = 0; i < ARRAY_SSIZE(str); i++) {
if (!fgets(buff, sizeof(buff), fp))
break;
len = strlen(buff);
s = buff;
for (ptrdiff_t j = 0; ((s - buff) < len) &&
(j < ARRAY_SSIZE(str[0])); s += n+1, j++) {
n = 0;
if (sscanf(s, " %9[^ ,()\n]%n", str[i][j], &n) == EOF)
break;
}
}
for (ptrdiff_t i = 0; i < ARRAY_SSIZE(str); i++) {
for (ptrdiff_t j = 0; j < ARRAY_SSIZE(str[0]); j++) {
if (str[i][j][0])
printf("%s\n", str[i][j]);
}
}
return 0;
}
Я разделил каждую строку, чтобы вы могли играть с ними отдельно, если вам это нужно.
Это самая важная строка:
if (sscanf(s, " %9[^ ,()\n]%n", str[i][j], &n) == EOF)
break;
она читает из строкиs
, " %9[^ ,()\n]"
отбрасывает все пробелы и принимает массив char
с, пока не будет найден первый из следующих символов: " ,()\n"
или пока он не достигнет максимальной длины 9 (9 + '\0'
= 10),строка хранится в str[i][j]
;после этого "%n"
сохраняет в n
количество символов, использованных в буфере, так что вы можете обновить char *
так, чтобы он указывал сразу после следующего непрочитанного символа (фактически один за этим, потому что мы знаем, что первыйнепрочитанный символ будет запятой или чем-то в этом роде, поэтому это будет символ, который нам не нужен. Эта работа (обновление указателя) выполняется в следующей строке:
for (ptrdiff_t j = 0; ((s - buff) < len) &&
(j < ARRAY_SSIZE(str[0])); s += n+1, j++) {