Мне нужно прочитать текстовый файл со строками, сформированными следующим образом:
1: (G, 2), (F, 3) 2: (G, 2), (F, 3) 3: (F, 4), (G, 5) 4: (F, 4), (G, 5) 5: (F, 6), (c, w) 6: (p, f), (G, 7) 7: (G, 7), (G, 7) w: (c, w), (c, w)
Каждая строка будет снабжать структуру своими данными (5 цифрами или буквами в ней) .
Как лучше всего прочитать строку и получить нужные строки?
В настоящее время я использую длинную последовательность условий с использованием fgetc, но это кажется уродливым и не очень умным.
Я не могу использовать массивы, потому что строки могут различаться по размеру, если числа состоят из двух цифр.





fgets () и sscanf () насколько я помню
Используйте fgets():
#include <stdio.h>
int main(void)
{
char line[256];
while(fgets(line, sizeof(line), stdin) != NULL) // fgets returns NULL on EOF
{
// process line; line is guaranteed to be null-terminated, but it might not end in a
// newline character '\n' if the line was longer than the buffer size (in this case,
// 256 characters)
}
return 0;
}Я думаю, вы могли бы разобрать его по строкам:
fscanf(file,"%c: (%c, %c), (%c, %c)", &first,&second,&third,&fourth,&fifth);
Я пробовал это сделать, но получил только ошибки сегментации, попробую еще раз, на всякий случай что-то пропустил
на самом деле, если первый, второй, третий и т. д. не выделены указатели, вам нужно сделать: fscanf (file, "% c: (% c,% c)", & first, & second, & third); или вы получите сбои сегментов, потому что вы будете разыменовывать недопустимые адреса ...
Хороший звонок, исправлено ... Я ни в коем случае не C-разработчик.
Это не обрабатывает значения длиной более одного символа, @Gabe указал, что числа могут состоять как минимум из 2 цифр.
Также возникают проблемы с первой новой строкой!
fscanf работает довольно хорошо, но вам придется использовать преобразования строк, потому что символы не будут работать для чисел с более чем одной цифрой.
Разве это не домашнее задание?
#include <stdio.h>
void main(int argc, char **argv) {
FILE * f;
f = fopen(argv[1], "r");
while (1) {
char char_or_num[32][5]; // five string arrays, up to 32 chars
int i;
int did_read;
did_read = fscanf(f, "%32[0-9a-zA-Z]: (%32[0-9a-zA-Z], %32[0-9a-zA-Z]), (%32[0-9a-zA-Z], %32[0-9a-zA-Z])\n", char_or_num[0], char_or_num[1], char_or_num[2], char_or_num[3], char_or_num[4]);
if (did_read != 5) {
break;
}
printf("%s, %s, %s, %s, %s\n", char_or_num[0], char_or_num[1], char_or_num[2], char_or_num[3], char_or_num[4]);
}
fclose(f);
}
Не используйте void main (...); это нестандартно.
#include
void
f()
{
FILE* fp;
if ( (fp = fopen("foo.txt", "r")) == NULL)
{
perror("fopen");
return;
}
char ch[5];
while (fscanf(fp, "%c: (%c, %c), (%c, %c)\n", &ch[0], &ch[1], &ch[2], &ch[3], &ch[4]) == 5)
{
printf("--> %c %c %c %c %c\n", ch[0], ch[1], ch[2], ch[3], ch[4]);
}
fclose(fp);
}
В основном вам нужно будет сохранить позицию файла ptr через fgetpos, пройти до конца строки (независимо от того, как вы его определяете), сохранить этот размер, fsetpos в предыдущую позицию, выделить буфер, достаточно большой, чтобы удерживать строку, а затем вызовите fread с новым буфером.
Вам вообще не нужно этого делать. fgets () отлично работает. Если вы не возражаете против всех предостережений fscanf (), это тоже работает. Оба показаны здесь.
Вау - это будет тяжелая работа; Кстати, излишне тяжелая работа. Для первого выбора используйте fgets (); fscanf (), если вы чувствуете себя смелым и имеете дело с новыми строками.
Проблема с использованием fgets () заключается в том, что это заставляет вас угадывать размер строки, и если вы не будете внимательно и должным образом проверять возвращаемые значения, чтобы убедиться, что вы получили всю строку, ваш единственный вызов функции может превратиться во множество вызовов до тех пор, пока вы получите нужный размер.
Предполагая, что у вас есть правильные переменные, это должно сработать:
fscanf(fp, "%[^:]: (%[^,], %[^)]), (%[^,], %[^)])", a, b, c, d, e);
fp - это указатель на файл и от "a" до "e" - указатели на символы
#include <stdio.h>
int main (void)
{
char buf[81]; /* Support lines up to 80 characters */
char parts[5][11]; /* Support up to 10 characters in each part */
while (fgets(buf, sizeof(buf), stdin) != NULL)
{
if (sscanf(buf, "%10[^:]: (%10[^,], %10[^)]), (%10[^,], %10[^)])",
parts[0], parts[1], parts[2], parts[3], parts[4]) == 5)
{
printf("parts: %s, %s, %s, %s, %s\n",
parts[0], parts[1], parts[2], parts[3], parts[4]);
}
else
{
printf("Invalid input: %s", buf);
}
}
return 0;
}
Пробный прогон:
$ ./test
1: (G, 2), (F, 3)
2: (G, 2), (F, 3)
3: (F, 4), (G, 5)
4: (F, 4), (G, 5)
5: (F, 6), (c, w)
6: (p, f), (G, 7)
7: (G, 7), (G, 7)
w: (c, w), (c, w)
parts: 1, G, 2, F, 3
parts: 2, G, 2, F, 3
parts: 3, F, 4, G, 5
parts: 4, F, 4, G, 5
parts: 5, F, 6, c, w
parts: 6, p, f, G, 7
parts: 7, G, 7, G, 7
parts: w, c, w, c, w
Если последнее значение во входных данных превышает 10 символов, оно будет усечено без указания ошибки, если это неприемлемо, вы можете использовать спецификатор преобразования %c в качестве шестого аргумента для захвата следующего символа после последнего значения и убедиться, что это закрывающая скобка.
похоже на домашнее задание, пожалуйста, добавьте тег домашнего задания, если так