Это мой первый вопрос на этом сайте, и я только начал программировать, пожалуйста, проявите ко мне терпение. У меня проблемы с этим кодом при чтении строк и промежуточных чисел из файла, они разделены точкой с запятой ";" и начинается с количества строк. Файл выглядит примерно так:

13;
A;15;B;1;0;0;0;
A;9;C;0;3;2;0;
A;9;D;0;4;0;2;
A;3;E;2;3;2;0;
A;7;F;5;5;3;1;
A;5;G;5;7;6;0;
A;13;H;0;0;0;0;
A;1;I;8;1;0;0;
A;1;J;2;2;1;0;
A;6;K;7;3;2;0;
A;5;L;2;4;3;0;
A;12;AA;0;3;2;0;
A;9;BA;0;1;0;0;

Я попытался создать функцию, которая будет получать указатель файла (fp) и количество строк, которые были прочитаны в основной функции. Он будет читать файл и сохранять промежуточные числа и строки в матрицах:

#include<stdio.h>
#include<stdlib.h>

char timesjogos[100][2][100];
int golsjogos[100][3];
int faltasjogos[100][3];
int camajogos[100][3];
int cverjogos[100][3];

int ReadGames(FILE *caminho,int njogos){
    printf("starting to read jogos.\n");
    int i=0;
    while(fscanf(caminho, " %[^;];%d[^;];%[^;];%d[^;];%d[^;];%d[^;];%d[^;];",
        timesjogos[i][0], &golsjogos[i][0], timesjogos[i][1], &golsjogos[i][1],
        &faltasjogos[i][0], &camajogos[i][0], &cverjogos[i][0]) == 7)
   {
        if(i < njogos)
            i++;
        else
            break;
    }    
}

int main()
{
    FILE *fp;
    int nbets;
    fp = fopen("jogos.txt", "r");
    if (!fp){
        printf ("Error trying to open file.");
    }
    fscanf(fp, " %d[^;];", &nbets);
    ReadGames(fp, nbets);
}

Мои сомнения касаются% [^;]; Я читал каждую строку до; , я должен использовать% d [^;] для промежуточных чисел? Как правильно это делать?

Кроме того, я использую глобальные переменные для сохранения прочитанной информации, проблема в том, что они могут быть недостаточно большими, чтобы сохранить огромное количество строк (мой профессор сделал файл из 24180 строк для проверки наших кодов). Я думал об использовании количества строк, которые он дает в первой строке, для создания предварительно заданных матриц внутри функции, но как я могу вернуть или сохранить его после завершения функции?

Прошу прощения за огромный код, но я хотел показать все детали. Буду очень благодарен за более опытную помощь: D

1
user3203734 25 Янв 2014 в 05:58
Попробуйте std :: getline (string, ';').
 – 
Thomas Matthews
25 Янв 2014 в 05:59
1
@ThomasMatthews: Когда std::getline стал доступен на C?
 – 
Ken White
25 Янв 2014 в 06:03
Мне нужно хранить промежуточные числа и строки отдельно, будет ли это хранить всю строку?
 – 
user3203734
25 Янв 2014 в 06:03
Это поможет точно знать, что вы должны делать с целыми числами и строками. Хранить их в отдельных файлах? В каком формате? Поскольку я не могу читать на вашем языке (испанском?), Я с трудом могу получить эту информацию из исходного файла :)
 – 
kuroi neko
25 Янв 2014 в 06:05
«Мои сомнения насчет» - пробовали ли вы скомпилировать и запустить свой код? Что произойдет, когда вы это сделаете? Он компилируется? Это работает? Считывает ли он правильные значения в правильные массивы? Вы можете создать уменьшенную версию файла для начальных тестов, а затем перейти к реальной, когда она будет работать над небольшой.
 – 
Ken White
25 Янв 2014 в 06:09

1 ответ

Лучший ответ

Обозначение %[^;] считывает строку, состоящую из любого количества точек с запятой. Анализ останавливается, когда встречается точка с запятой. В случае чисел разбор в любом случае останавливается на точке с запятой; точка с запятой не является частью представления числа.

Использование вами %d[^;] означает, что fscanf() ищет целое число (%d), затем открытую квадратную скобку, курсор, точку с запятой и закрывающую квадратную скобку. Конечно, они не появляются во входных данных, поэтому сканирование не выполняется.

Следовательно, ваш цикл ввода, вероятно, должен быть:

while (fscanf(caminho, " %[^;];%d;%[^;];%d;%d;%d;%d;",
              timesjogos[i][0], &golsjogos[i][0], timesjogos[i][1],
              &golsjogos[i][1], &faltasjogos[i][0], &camajogos[i][0],
              &cverjogos[i][0]) == 7)
{
    ...
}

Вы можете указать максимальную длину для спецификаций преобразования %[^;]; %99[^;] было бы уместным, поскольку третье измерение timesjogos равно 100. Существует разница между указанной длиной и используемой длиной (закрепленной в древней истории; так было до первый стандарт C, и стандарт C кодифицировал существующую практику).

1
Jonathan Leffler 25 Янв 2014 в 06:38
Итак,% [^;] будет читать все как строку? Или тип вектора будет определять, строка это или целое число? Спасибо, что ответили так быстро, кстати.
 – 
user3203734
25 Янв 2014 в 06:25
Я не уверен, что вы имеете в виду под «типом вектора», но %[xyz] - это спецификация преобразования, которая считывает строку (в этом примере, состоящую из букв x, y или z). Это похоже на %s, за исключением того, что вы можете указать, какие символы подходят. Когда вы пишете %d[^;], у вас есть одна спецификация преобразования (%d), за которой следуют четыре символа, которые, поскольку им не предшествует %, не являются частью спецификации преобразования и поэтому стоят сами за себя; символы должны появиться во входных данных, чтобы сканирование продолжалось после этой точки в строке формата.
 – 
Jonathan Leffler
25 Янв 2014 в 06:33