Я решил сделать это построчно, а не посимвольно, и, хотя я думаю, что это неоправданно усложняет этот конкретный пример, вы должны увидеть, как вы можете построить этот пример.
Например, переменная token
просто сидит там бесполезно, за исключением одного раза, когда она используется в качестве проверки для цикла while
.На самом деле вы можете начать читать эти значения по мере их поступления или повторять итерацию по файлу во второй раз, точно зная параметры rows
и cols
, так что тогда будет простоscanf
'значения и проверка возвращаемого значения, чтобы убедиться, что ничего странного не пошло вниз.
Это в основном сводится к компромиссу между временем и использованием памяти, поэтому решение, вероятно, будет включать другой параметр в окончательныйрешение, такое как ограничения по срокам.
В любом случае, я думаю, мы все можем согласиться, что было бы проще потребовать от пользователя включить количество строк и столбцов, а не заставлять нас искать их.
Надеюсь, это поможет, удачи!
#define DEFAULT_BUFFER_LENGTH (512)
int main(int argc, char *argv[])
{
const char* inputFilename = (argc == 1) ? "matrix" : argv[argc - 1];
FILE *inputFile = fopen(inputFilename, "r");
if (!inputFile){
printf("Could not open specified file");
return EXIT_FAILURE;
}
char inputBuffer[DEFAULT_BUFFER_LENGTH];
memset(inputBuffer, 0, DEFAULT_BUFFER_LENGTH);
char* separator = " ";
char* token = NULL;
size_t rows = 0;
size_t cols = 0;
size_t prev = 0;
while (fgets(inputBuffer, DEFAULT_BUFFER_LENGTH - 1, inputFile)) {
/** Save the current value of columns. I'm checking the number of tokens
* in every column because I think it would be a good idea to validate
* that the matrix is indeed a rectangle, but I didn't implement that
* check here.
*
* In the event that the file has something weird, like a trailing new
* line, this preserved value allows us to backtrack and preserve the
* correct value.
*
*/
prev = cols;
cols = 0;
++rows;
if ((token = strtok(inputBuffer, separator))) {
++cols;
while (token) {
token = strtok(NULL, separator);
if (token) {
++cols;
}
}
}
/** If we reach the end of the line without having found any tokens
* we have probably reached the last new line character before the end
* of the file. Set the 'cols' value to the value of the last actual
* line.
*
* Also remember to correct the 'rows' variable by reducing it by one.
*
*/
if (!cols) {
cols = prev;
--rows;
}
}
printf("%lu x %lu\n", rows, cols);
return EXIT_SUCCESS;
}