C++ Написать функцию, которая находит в файле самое длинное число в строке

Текст задания такой - напишите функцию, которая находит и печатает самую длинную строку чисел в файле. Если есть несколько строк такой длины, распечатайте ту, которая представляет наибольшее число. Предскажите, что числовые строки могут быть произвольно длинными. Сообщите соответствующим образом, если в файле вообще нет цифр. Например, «alpha321beta456gamma123» → 456.

Мой код такой, это все, что я сумела написать:

#include <iostream>
#include <fstream>
using namespace std;

string longestInteger(string str, fstream &f1) {
    int count = 0, max = 0, pos = -1, pre_pos, pre_len, len = 0;
    int i;
    while (getline (f1, str)) {
        cout << str;
        pre_pos = pos;
        pre_len = len;
        count = 0;
        len = 0;
    }

//    for (int i = 0; i < &f1; i++) {
//         pre_pos = pos;
//         pre_len = len;
//         count = 0;
//         len = 0;

        if (isdigit(str[i]))
            pos = i;

        while (isdigit(str[i])) {
            count++;
            i++;
            len++;
        }

        if (count > max) {
            max = count;
        }
        else {
            pos = pre_pos;
            len = pre_len;
        }
    }
    return (str.substr(pos, len));
}

int main() {

    ifstream fin ("in.txt");
    fstream f1;
    f1.open("in.txt", ios::in);
    string str;

    if (f1.is_open()) {
        f1 << "alpha321beta456gamma123";
        int l = str.length();
        cout << longestInteger(str, &f1);
    } else {
        cout << "Nevar atvērt failu!" << endl;
    }
    return 0;
}

Ответы (1 шт):

Автор решения: Павел Ериков

Объясню, как можно сделать:

  1. Для начала заголовок функции лучше изменить на string longestInteger(fstream& f)

    То есть функция принимает поток и возвращает результат типа string

  2. Как я понял вам нужно найти максимальную числовую последовательность во всем файле. Т.к. длина последовательности может быть очень большой и не помещаться даже в unsigned long long int, то будет хранить число в виде строки и сравнивать соответственно, как строки.

  3. Вам пригодится 5 переменных.

    1. Я оставил int i, но лучше изменить, на более понятное что-то типа index. Это просто будет итератор по считанной из файла строке

    2. int str_size пригодится часто получать размер считанной строки, так что лучше после после чтения строки, сохранить её длину.

    3. string line сюда будет считываться строка из файла

    4. string max_num = "" думаю понятно, что переменная отвечает за максимальное число в файле, её мы и будем возвращать в конце функции.

    5. string num = "" сюда мы будем заносить найденное число, а потом сравнивать в max_num.

  4. Первое, что нужно сделать это считать строку из файла, у вас есть этот момент в коде. getline(f, line) в нашем случае. (И понятное дело в условии цикла while)

  5. После чтения строки, как у вас в коде, можно вывести строку в консоль, а так же нужно обнулить счетчик i и присвоить str_size line.size()

  6. Теперь надо проанализировать считанную строку.

    Пишем цикл while(i < str_size). В нем я привык сначала находить начало числовой последовательности, то есть циклом проходить по строке, пока не наткнуть на цифру. Мне удобней использовать такую проверку line[i] < '0' || line[i] > '9' вместо функции isdigit

    while (i < str_size && (line[i] < '0' || line[i] > '9'))
        ++i;
    

    После цикла выше i будет равен или индексу первого вхождения цифры или str_size.

  7. Теперь запишем так же в цикле идет по строке, пока символ является цифрой и записываем его в num

    while (i < str_size && line[i] >= '0' && line[i] <= '9') {
        num += line[i];
        i++;
    }
    
  8. Осталось всего лишь сравнить две строки. Но для этого не подойдет просто функция strcmp или оператор сравнения у string. Т.к. они не обращают внимания на длину строки.

    Написал не большую функцию:

    //Возвращает -1, если left < right
    //Возвращает 1, есть right > left
    //И 0 если они равны
    int str_compare(string& left, string& right) {
        if (left.size() < right.size()) return -1;
        if (left.size() > right.size()) return 1;
        return strcmp(left.c_str(), right.c_str());
    }
    

    Если max_num меньше num, то присваиваем max_num = num, тут думаю все понятно.

  9. Очищаем num = ""

  10. Возвращаем max_num после все циклов.

Надеюсь понятно объяснил идею, если вам нужно, то вы прочитаете и поймете, если же нет, тогда извините полного кода я просто не скину :)

→ Ссылка