C++ std:: 문자열이 특정 문자열로 시작하는지 확인하고 하위 문자열을 int로 변환하려면 어떻게 해야 합니까?
C++에서 다음 (파이썬 유사 코드)를 어떻게 구현합니까?
if argv[1].startswith('--foo='):
foo_value = int(argv[1][len('--foo='):])
를 들어, if (예를들어만약, 약만▁()argv[1]
이라--foo=98
,그리고나서foo_value
이라98
.)
업데이트: Boost에 대해 알아보려 하지 않습니다. 단순한 명령줄 도구를 아주 조금 변경하려고 하기 때문입니다(작은 변경 사항에 대해 Boost를 연결하고 사용하는 방법을 배울 필요가 없습니다).
검색 위치를 차지하는 오버로드 사용pos
매개 변수 및 0을 전달합니다.
std::string s = "tititoto";
if (s.rfind("titi", 0) == 0) { // pos=0 limits the search to the prefix
// s starts with prefix
}
더 필요한 사람?순수 STL!
많은 사람들이 이것을 "접두사를 찾는 전체 문자열을 뒤로 검색"하는 의미로 잘못 읽었습니다.결과가 그면잘결나예니납다타가과된못러예(:다니).string("tititito").rfind("titi")
했을 때 를 반환합니다.== 0
false를 반환합니다. 그러면 비효율적입니다(시작만 보는 대신 전체 문자열을 살펴봅니다).하지만 그것은 그것이 통과하기 때문에 그렇게 하지 않습니다.pos
를 로의파라터미로 합니다.0
검색을 해당 위치 또는 이전 위치에서만 일치하도록 제한합니다.예:
std::string test = "0123123";
size_t match1 = test.rfind("123"); // returns 4 (rightmost match)
size_t match2 = test.rfind("123", 2); // returns 1 (skipped over later match)
size_t match3 = test.rfind("123", 0); // returns std::string::npos (i.e. not found)
이 작업은 다음과 같이 수행됩니다.
std::string prefix("--foo=");
if (!arg.compare(0, prefix.size(), prefix))
foo_value = std::stoi(arg.substr(prefix.size()));
Boost와 같은 lib를 찾고 있습니다.이를 수행하는 프로그램 옵션도 좋은 방법입니다.
완성도를 높이기 위해 C 방법을 언급하겠습니다.
한다면
str
문자열인 의당원끈입다니래신▁your입니다.substr
이고, 그 다음에 "는 " " " 입니다.
strncmp(str, substr, strlen(substr))
돌아올 것입니다
0
한다면str
합니다.substr
»strncmp
그리고.strlen
는 C 파일 C에 .<string.h>
(원래 야신 라우프가 여기에 게시했으며, 마크업 추가됨)
하지 않는 대문자를구않비경우의교는지분,strnicmp
에 strncmp
.
이것이 C 방법입니다. C++ 문자열에 대해 다음과 같은 동일한 기능을 사용할 수 있습니다.
strncmp(str.c_str(), substr.c_str(), substr.size())
Boost를 이미 사용 중인 경우 부스트 문자열 알고리즘 + 부스트 어휘 캐스트를 사용할 수 있습니다.
#include <boost/algorithm/string/predicate.hpp>
#include <boost/lexical_cast.hpp>
try {
if (boost::starts_with(argv[1], "--foo="))
foo_value = boost::lexical_cast<int>(argv[1]+6);
} catch (boost::bad_lexical_cast) {
// bad parameter
}
여기에 제공된 다른 많은 답변과 마찬가지로 이러한 종류의 접근 방식은 매우 간단한 작업에는 괜찮지만, 장기적으로 볼 때 일반적으로 명령줄 구문 분석 라이브러리를 사용하는 것이 좋습니다.부스트에는 (부스트)가 있습니다.Program_options)는 이미 Boost를 사용하고 있다면 의미가 있을 수 있습니다.
그렇지 않으면 "c++ 명령줄 파서"를 검색하면 여러 가지 옵션이 생성됩니다.
내가 직접 사용하는 코드:
std::string prefix = "-param=";
std::string argument = argv[1];
if(argument.substr(0, prefix.size()) == prefix) {
std::string argumentValue = argument.substr(prefix.size());
}
아직 아무도 STL 알고리즘/불일치 기능을 사용하지 않았습니다.true를 반환하는 경우 접두사는 'ToCheck' 접두사입니다.
std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()
전체 예제 프로그램:
#include <algorithm>
#include <string>
#include <iostream>
int main(int argc, char** argv) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "Will print true if 'prefix' is a prefix of string" << std::endl;
return -1;
}
std::string prefix(argv[1]);
std::string toCheck(argv[2]);
if (prefix.length() > toCheck.length()) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "'prefix' is longer than 'string'" << std::endl;
return 2;
}
if (std::mismatch(prefix.begin(), prefix.end(), toCheck.begin()).first == prefix.end()) {
std::cout << '"' << prefix << '"' << " is a prefix of " << '"' << toCheck << '"' << std::endl;
return 0;
} else {
std::cout << '"' << prefix << '"' << " is NOT a prefix of " << '"' << toCheck << '"' << std::endl;
return 1;
}
}
편집:
@James T처럼.Huggett은 다음 질문에 더 적합하다고 제안합니다. std:: equal:A는 B의 접두사이며 코드가 약간 짧습니다.
std::equal(prefix.begin(), prefix.end(), toCheck.begin())
전체 예제 프로그램:
#include <algorithm>
#include <string>
#include <iostream>
int main(int argc, char **argv) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "Will print true if 'prefix' is a prefix of string"
<< std::endl;
return -1;
}
std::string prefix(argv[1]);
std::string toCheck(argv[2]);
if (prefix.length() > toCheck.length()) {
std::cerr << "Usage: " << argv[0] << " prefix string" << std::endl
<< "'prefix' is longer than 'string'" << std::endl;
return 2;
}
if (std::equal(prefix.begin(), prefix.end(), toCheck.begin())) {
std::cout << '"' << prefix << '"' << " is a prefix of " << '"' << toCheck
<< '"' << std::endl;
return 0;
} else {
std::cout << '"' << prefix << '"' << " is NOT a prefix of " << '"'
<< toCheck << '"' << std::endl;
return 1;
}
}
C++17을 사용하면 & with C++20 또는 를 사용할 수 있습니다.
의 std::string_view
와비하여와 std::string
메모리 관리와 관련하여 - "문자열"(문자열과 유사한 개체의 연속적인 시퀀스)에 대한 포인터만 가지고 있으며 크기를 알고 있습니다.정수 값을 얻기 위해 소스 문자열을 이동/복사하지 않는 예:
#include <exception>
#include <iostream>
#include <string>
#include <string_view>
int main()
{
constexpr auto argument = "--foo=42"; // Emulating command argument.
constexpr auto prefix = "--foo=";
auto inputValue = 0;
constexpr auto argumentView = std::string_view(argument);
if (argumentView.starts_with(prefix))
{
constexpr auto prefixSize = std::string_view(prefix).size();
try
{
// The underlying data of argumentView is nul-terminated, therefore we can use data().
inputValue = std::stoi(argumentView.substr(prefixSize).data());
}
catch (std::exception & e)
{
std::cerr << e.what();
}
}
std::cout << inputValue; // 42
}
- 두 문 열 모 할 때 려 고 를 -을 고려하면,argv[1]
그리고."--foo"
C 문자열입니다. @FelixDombek의 대답은 실제 최고의 솔루션입니다.
하지만 다른 답변을 보니, 만약 당신의 텍스트가 이미 사용 가능하다면 주목할 가치가 있다고 생각했습니다.std::string
이제까지 언급되지 않았던 단순하고 복사 없이 효율적인 솔루션이 존재합니다.
const char * foo = "--foo";
if (text.rfind(foo, 0) == 0)
foo_value = text.substr(strlen(foo));
foo가 이미 문자열인 경우:
std::string foo("--foo");
if (text.rfind(foo, 0) == 0)
foo_value = text.substr(foo.length());
부터는 C++20을 할 수 .starts_with
방법.
std::string s = "abcd";
if (s.starts_with("abc")) {
...
}
text.substr(0, start.length()) == start
STL을 사용하면 다음과 같이 보일 수 있습니다.
std::string prefix = "--foo=";
std::string arg = argv[1];
if (prefix.size()<=arg.size() && std::equal(prefix.begin(), prefix.end(), arg.begin())) {
std::istringstream iss(arg.substr(prefix.size()));
iss >> foo_value;
}
C 컨스트럭츠를 사용한 것에 대해 비난을 받을 위험을 무릅쓰고, 저는 이것을 생각합니다.sscanf
예제는 대부분의 Boost 솔루션보다 더 우아합니다.그리고 Python 인터프리터가 있는 곳이라면 링크에 대해 걱정할 필요가 없습니다!
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
for (int i = 1; i != argc; ++i) {
int number = 0;
int size = 0;
sscanf(argv[i], "--foo=%d%n", &number, &size);
if (size == strlen(argv[i])) {
printf("number: %d\n", number);
}
else {
printf("not-a-number\n");
}
}
return 0;
}
이 선행하고 다은추적솔동 Python 코드행/처를고리하비다지가음다를 보다 더 하게 처리하는 몇 가지 입니다.atoi
접미사가 아닌 접미사를 잘못 무시합니다.
$ ./scan --foo=2 --foo=2d --foo='2 ' ' --foo=2'
number: 2
not-a-number
not-a-number
not-a-number
사용합니다std::string::compare
아래와 같은 유틸리티 방법으로 포장:
static bool startsWith(const string& s, const string& prefix) {
return s.size() >= prefix.size() && s.compare(0, prefix.size(), prefix) == 0;
}
C++20 업데이트:
- 사용하다
std::string::starts_with
https://en.cppreference.com/w/cpp/string/basic_string/starts_with
std::string str_value = /* smthg */;
const auto starts_with_foo = str_value.starts_with(std::string_view{"foo"});
C++20에는 이제 다음이 있습니다.starts_with
기로가능의 멤버 으로 사용 std::string
다음으로 정의됨:
constexpr bool starts_with(string_view sv) const noexcept;
constexpr bool starts_with(CharT c) const noexcept;
constexpr bool starts_with(const CharT* s) const;
따라서 코드는 다음과 같습니다.
std::string s{argv[1]};
if (s.starts_with("--foo="))
C++11 호환성이 필요하고 부스트를 사용할 수 없는 경우 사용 예를 들어 다음과 같은 부스트 호환 드롭인이 있습니다.
#include <iostream>
#include <string>
static bool starts_with(const std::string str, const std::string prefix)
{
return ((prefix.size() <= str.size()) && std::equal(prefix.begin(), prefix.end(), str.begin()));
}
int main(int argc, char* argv[])
{
bool usage = false;
unsigned int foos = 0; // default number of foos if no parameter was supplied
if (argc > 1)
{
const std::string fParamPrefix = "-f="; // shorthand for foo
const std::string fooParamPrefix = "--foo=";
for (unsigned int i = 1; i < argc; ++i)
{
const std::string arg = argv[i];
try
{
if ((arg == "-h") || (arg == "--help"))
{
usage = true;
} else if (starts_with(arg, fParamPrefix)) {
foos = std::stoul(arg.substr(fParamPrefix.size()));
} else if (starts_with(arg, fooParamPrefix)) {
foos = std::stoul(arg.substr(fooParamPrefix.size()));
}
} catch (std::exception& e) {
std::cerr << "Invalid parameter: " << argv[i] << std::endl << std::endl;
usage = true;
}
}
}
if (usage)
{
std::cerr << "Usage: " << argv[0] << " [OPTION]..." << std::endl;
std::cerr << "Example program for parameter parsing." << std::endl << std::endl;
std::cerr << " -f, --foo=N use N foos (optional)" << std::endl;
return 1;
}
std::cerr << "number of foos given: " << foos << std::endl;
}
왜 gnu getopts를 사용하지 않습니까?다음은 기본적인 예입니다(안전 점검 없음).
#include <getopt.h>
#include <stdio.h>
int main(int argc, char** argv)
{
option long_options[] = {
{"foo", required_argument, 0, 0},
{0,0,0,0}
};
getopt_long(argc, argv, "f:", long_options, 0);
printf("%s\n", optarg);
}
다음 명령의 경우:
$ ./a.out --foo=33
얻게 될 것입니다.
33
좋아요, 왜 도서관이나 그런 것들의 복잡한 사용인가요?C++ 문자열 개체는 [] 연산자를 오버로드하므로 문자를 비교하기만 하면 됩니다.방금 한 것처럼 디렉터리에 있는 모든 파일을 나열하고 보이지 않는 파일과 ... 및 . 의사 파일을 무시하고 싶기 때문입니다.
while ((ep = readdir(dp)))
{
string s(ep->d_name);
if (!(s[0] == '.')) // Omit invisible files and .. or .
files.push_back(s);
}
그 정도로 간단한..
사용할 수도 있습니다.strstr
:
if (strstr(str, substr) == substr) {
// 'str' starts with 'substr'
}
하지만 문자열이 실제로 'substr'로 시작하지 않을 때는 전체 문자열을 반복해야 하기 때문에 짧은 문자열에만 적합하다고 생각합니다.
C++11 이상 사용 가능find()
그리고.find_first_of()
찾기를 사용한 단일 문자 찾기 예제:
#include <string>
std::string name = "Aaah";
size_t found_index = name.find('a');
if (found_index != std::string::npos) {
// Found string containing 'a'
}
찾기를 사용하여 전체 문자열을 찾고 위치 5부터 시작하는 예:
std::string name = "Aaah";
size_t found_index = name.find('h', 3);
if (found_index != std::string::npos) {
// Found string containing 'h'
}
사용 예find_first_of()
첫 번째 문자만 검색할 수 있습니다.
std::string name = ".hidden._di.r";
size_t found_index = name.find_first_of('.');
if (found_index == 0) {
// Found '.' at first position in string
}
행운을 빕니다.
std::string text = "--foo=98";
std::string start = "--foo=";
if (text.find(start) == 0)
{
int n = stoi(text.substr(start.length()));
std::cout << n << std::endl;
}
C++11은 더 복잡한 표현을 일치시키는 데도 사용될 수 있기 때문입니다.다음 예제에서는 또한 전체를 통해 부동 숫자를 처리하고 다음으로 캐스트합니다.int
.
하만지그, 그▁however.parseInt
아래에 표시된 방법은 접두사가 일치하지 않을 경우 예외를 발생시킬 수 있습니다. 이는 주어진 응용 프로그램에 따라 쉽게 조정될 수 있습니다.
#include <iostream>
#include <regex>
int parseInt(const std::string &str, const std::string &prefix) {
std::smatch match;
std::regex_search(str, match, std::regex("^" + prefix + "([+-]?(?=\\.?\\d)\\d*(?:\\.\\d*)?(?:[Ee][+-]?\\d+)?)$"));
return std::stof(match[1]);
}
int main() {
std::cout << parseInt("foo=13.3", "foo=") << std::endl;
std::cout << parseInt("foo=-.9", "foo=") << std::endl;
std::cout << parseInt("foo=+13.3", "foo=") << std::endl;
std::cout << parseInt("foo=-0.133", "foo=") << std::endl;
std::cout << parseInt("foo=+00123456", "foo=") << std::endl;
std::cout << parseInt("foo=-06.12e+3", "foo=") << std::endl;
// throw std::invalid_argument
// std::cout << parseInt("foo=1", "bar=") << std::endl;
return 0;
}
정규식 패턴의 마법의 종류는 다음 답변에서 잘 설명되어 있습니다.
편집: 이전 응답이 정수로 변환되지 않았습니다.
if(boost::starts_with(string_to_search, string_to_look_for))
intval = boost::lexical_cast<int>(string_to_search.substr(string_to_look_for.length()));
이것은 완전히 검증되지 않았습니다.원리는 파이썬과 동일합니다.부스트가 필요합니다.StringAlgo 및 Boost.어휘 캐스트.
문자열이 다른 문자열로 시작하는지 확인한 다음 첫 번째 문자열의 하위 문자열('슬라이스')을 가져와 어휘 캐스트를 사용하여 변환합니다.
언급URL : https://stackoverflow.com/questions/1878001/how-do-i-check-if-a-c-stdstring-starts-with-a-certain-string-and-convert-a
'programing' 카테고리의 다른 글
Git를 사용하여 모든 분기에서 문자열을 검색하려면 어떻게 해야 합니까? (0) | 2023.05.06 |
---|---|
Xcode 빌드 설정에서 "아키텍처"와 "유효한 아키텍처"의 차이점은 무엇입니까? (0) | 2023.05.06 |
git: 새 파일을 포함한 모든 작업 dir 변경 실행 취소 (0) | 2023.05.06 |
컬렉션이 있을 때 VBA에서 어레이를 사용하는 이유는 무엇입니까? (0) | 2023.05.06 |
SQLAlchemy create_all()이 테이블을 생성하지 않습니다. (0) | 2023.05.06 |