Ваша основная проблема, связанная с 'A'
или целым числом в качестве значения, связана с неправильным пониманием того, что A
может быть проанализирован с sscanf
с использованием спецификатора формата "%d"
, он может 'т.Зачем?Когда вы пытаетесь выполнить синтаксический анализ 'A'
с "%d"
a , происходит сбой сопоставления , дальнейшие символы не извлекаются из буфера ввода, и return для sscanf
будет числомуспешных преобразований, имевших место до сбоя.
Если у вас есть данные разных типов, например
RED A
RED 2
Для анализа значений для A
или 2
,для этого потребуются два различных выражения sscanf
, которые можно легко различить, просто проверив return для sscanf
.Вы делаете это в условном выражении, и если синтаксический анализ с "%s %d"
завершается неудачно, вы пытаетесь выполнить анализ с помощью "%s %c"
и проверяете, успешно ли это произошло.
Например, скажем, вместо выделения с помощью malloc
(вы неперераспределение в любом случае), вы просто объявляете массив struct для хранения color
и value
чтения из каждой строки, например,
...
#define MAXCOLR 14
#define MAXLINE 100
#define MAXCHR 1024 /* don't skimp on read buffer size */
typedef struct { /* simple struct to associate each color/value */
char color[MAXCOLR];
int value;
} colorval_t;
int main (int argc, char **argv) {
size_t ndx = 0; /* index */
char buf[MAXCHR]; /* read buffer */
colorval_t arr[MAXLINE] = {{ .color = "" }}; /* array of struct */
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
...
while (ndx < MAXLINE && fgets (buf, MAXCHR, fp)) {
char c; /* temp char to use for parsing 2nd case */
if (sscanf (buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
ndx++;
else if (sscanf (buf, "%13s %c", arr[ndx].color, &c) == 2) {
arr[ndx].value = c;
ndx++;
}
}
Цикл while
выше является рабочим кодом для обработки анализаинформации, прочитанной из каждой строки в buf
.Первый вызов sscanf
пытается проанализировать строку и целочисленное значение.Если возвращаемое значение не равно 2
, то выполняется второй вызов sscanf
, чтобы попытаться проанализировать содержимое в строку и символ.Если это удастся, символьному значению (например, значению ASCII для символа) присваивается значение value
, которое, по вашему вопросу, соответствует вашему.
Добавление нескольких проверок и вывод color
и value
для каждой структуры, содержащейся в arr
, вы можете сделать что-то вроде следующего.( примечание: программа берет имя файла для чтения в качестве первого аргумента или читает из stdin
по умолчанию, если аргумент не указан. Не указывайте имена файлов жестко. Либо передайте имя файла в качестве аргумента, либо запроситеего запись)
#include <stdio.h>
#define MAXCOLR 14
#define MAXLINE 100
#define MAXCHR 1024 /* don't skimp on read buffer size */
typedef struct {
char color[MAXCOLR];
int value;
} colorval_t;
int main (int argc, char **argv) {
size_t ndx = 0;
char buf[MAXCHR];
colorval_t arr[MAXLINE] = {{ .color = "" }};
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (ndx < MAXLINE && fgets (buf, MAXCHR, fp)) {
char c;
if (sscanf (buf, "%13s %d", arr[ndx].color, &arr[ndx].value) == 2)
ndx++;
else if (sscanf (buf, "%13s %c", arr[ndx].color, &c) == 2) {
arr[ndx].value = c;
ndx++;
}
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (size_t i = 0; i < ndx; i++)
printf ("arr[%2zu] : %-14s %d\n", i, arr[i].color, arr[i].value);
return 0;
}
( примечание: использование модификатора ширина поля 13
для защиты границ массива символов для color
)
Пример использования / вывода
Использование ваших данных в качестве входных данных приведет к следующему:
$ ./bin/rdcolorval <dat/colorval.txt
arr[ 0] : RED 65
arr[ 1] : RED 2
arr[ 2] : RED 3
arr[ 3] : RED 4
arr[ 4] : RED 5
arr[ 5] : RED 6
arr[ 6] : RED 7
arr[ 7] : RED 8
arr[ 8] : RED 9
arr[ 9] : RED 10
arr[10] : RED 74
arr[11] : RED 81
arr[12] : RED 75
Просмотрите все и дайте мне знать, если выесть дополнительные вопросы.