Самый простой способ - использовать класс Scanner
в Java и объект FileReader. Простой пример:
Scanner in = new Scanner(new FileReader("filename.txt"));
Scanner
имеет несколько методов для чтения в строках, числах и т. Д. Вы можете найти дополнительную информацию об этом на странице документации Java.
Например, прочитав весь контент в String
:
StringBuilder sb = new StringBuilder();
while(in.hasNext()) {
sb.append(in.next());
}
in.close();
outString = sb.toString();
Также, если вам нужна конкретная кодировка, вы можете использовать это вместо FileReader
:
new InputStreamReader(new FileInputStream(fileUtf8), StandardCharsets.UTF_8)
без перегрузки
blockquote>, но перегрузка здесь делает код простым:
template<typename ... Ts> void doSomething(MyClass_one, Ts...two){ cout << "im one" << endl; } template<typename ... Ts> void doSomething(MyClass_two, Ts...two){ cout <<"im two" << endl; }
Если вы можете использовать C ++ 17, вы можете использовать if constexpr
:
template<typename T, typename ... Ts>
void doSomething(T one, Ts...two){
if constexpr ( isOne<T>::value ) { cout << "im one" << endl;}
else if constexpr ( isTwo<T>::value){ cout <<"im two" << endl;}
}
Конечно, isOne<T>::value
и isTwo<T>::value
должны быть static constexpr
переменными.
Если вы хотите проверить типы первого аргумента функции, применяется тот же подход, только нет необходимости что-то вроде isOne
и isTwo
, вы можете использовать std::is_same_v
, чтобы увидеть, если первый аргумент - MyClassOne
или MyClassTwo
:
#include <iostream>
#include <type_traits>
#include <vector>
class MyClassOne {};
class MyClassTwo {};
template<typename T, typename ... Ts>
void doSomething(T one, Ts...two){
if constexpr ( std::is_same_v<T, MyClassOne> )
std::cout << "im one" << std::endl;
else if constexpr ( std::is_same_v<T, MyClassTwo> )
std::cout <<"im two" << std::endl;
else
static_assert(false, "Only MyClassOne and MyClassTwo are permitted first arguments.");
}
int
main(int argc, char **argv) {
MyClassOne one;
MyClassTwo two;
doSomething(one, 1.5, two);
doSomething(two, 'c', one);
std::vector<MyClassOne> onesVector;
doSomething(onesVector, 1.0);
}
std::is_same_v<A,B>
приводит к значению true
, если типы A
и B
совпадают. Это отвечает на ваш вопрос: «если параметром один является MyClass_one, он должен вывести« im one », если его MyClass_two должен вывести« im two ».», И завершается неудачно во время компиляции, если первый аргумент имеет тип, отличный от etither myClassOne
или [ 1116]. [1 123]
Редактировать : добавлен static_assert
, который гарантирует, что компиляция завершится неудачно, если первым аргументом будет что-то еще, кроме MyClassOne
или MyClassTwo
, как это было предложено Джастином Таймом в комментарии.
Я бы предложил разделить вашу функцию на две части. Оставьте итеративную часть doSomething
и выделите то, что вы хотите сделать.
template<typename T> void theThing(T one);
template<>
void theThing<MyClass_one>(MyClass_one one) {
cout << "im one" << endl;
}
template<>
void theThing<MyClass_two>(MyClass_two one) {
cout << "im two" << endl;
}
template<typename T, typename ... Ts>
void doSomething(T one, Ts...two) {
theThing(one);
}
Таким образом, вы можете иметь специализированные вещи для каждого класса, который вы хотите использовать. Бонус, он не будет компилироваться для типов, для которых theThing
не специализируется.