scanf를 사용하여 std:: 문자열로 읽습니다.
제목 그대로 스캔프로 C++ 문자열을 읽을 수 있는 방법이 있는지 궁금합니다.
각 문자를 읽고 해당 문자열에 삽입할 수 있다는 것을 알고 있지만 다음과 같은 것을 원합니다.
string a;
scanf("%SOMETHING", &a);
gets()
또한 작동하지 않습니다.
미리 감사드립니다!
될 수 있습니다.
char tmp[101];
scanf("%100s", tmp);
string a = tmp;
그 아래에는 어떤 상황도 없습니다.gets()
사용됩니다!사용하는 것은 항상 잘못된 것입니다.gets()
그리고 C11로부터 제거되고 C++14로부터 제거됩니다.
scanf()
C++ 클래스를 지원하지 않습니다.그러나 결과를 저장할 수 있습니다.scanf()
로std::string
:
편집자 참고 사항:아래 코드는 댓글로 설명한 것과 같이 잘못된 코드입니다.정확한 접근 방법은 파타토, 톰, 다니엘 트러그먼의 답변을 참조하십시오.
std::string str(100, ' ');
if (1 == scanf("%*s", &str[0], str.size())) {
// ...
}
버퍼 길이를 지정하는 방법에 대해 완전히 확신할 수 없습니다.scanf()
그리고 매개변수들이 어떤 순서로 가느냐에 따라 ( 매개변수들이&str[0]
그리고.str.size()
다시 돌려야 하는데 제가 놓쳤을 수도 있습니다..
(형식 문자열로 입력합니다.그 결과는 다음과 같습니다.std::string
종료 Null 문자가 포함되며 크기가 변경되지 않습니다.
물론이죠, 저는 그냥.if (std::cin >> str) { ... }
하지만 그건 다른 질문입니다.
문제 설명:
의 기본 버퍼를 채울 수 있습니다.std::string
사용.scanf
, 하지만(!) 관리자가std::string
개체는 변경 내용을 인식하지 못합니다.
const char *line="Daniel 1337"; // The line we're gonna parse
std::string token;
token.reserve(64); // You should always make sure the buffer is big enough
sscanf(line, "%s %*u", token.data());
std::cout << "Managed string: '" << token
<< " (size = " << token.size() << ")" << std::endl;
std::cout << "Underlying buffer: " << token.data()
<< " (size = " << strlen(token.data()) << ")" << std::endl;
출력:
Managed string: (size = 0)
Underlying buffer: Daniel (size = 6)
여기서 무슨 일이 있었던 거지?내보낸 공식 API를 통해 수행되지 않은 변경 사항을 개체가 인식하지 못합니다.
기본 버퍼를 통해 개체에 쓸 때 데이터가 변하지만 문자열 개체는 이를 인식하지 못합니다.
원래 호출을 대체할 경우:token.reseve(64)
와 함께token.resize(64)
, 관리되는 문자열의 크기를 변경하는 호출의 결과는 달라졌을 것입니다.
const char *line="Daniel 1337"; // The line we're gonna parse
std::string token;
token.resize(64); // You should always make sure the buffer is big enough
sscanf(line, "%s %*u", token.data());
std::cout << "Managed string: " << token
<< " (size = " << token.size() << ")" << std::endl;
std::cout << "Underlying buffer: " << token.data()
<< " (size = " << strlen(token.data()) << ")" << std::endl;
출력:
Managed string: Daniel (size = 64)
Underlying buffer: Daniel (size = 6)
다시 한 번 말하지만 결과는 차선입니다.출력은 맞지만 사이즈는 맞지 않습니다.
해결책:
이렇게 하려면 다음 단계를 수행합니다.
- 불러
resize
완충장치가 충분한지 확인할 수 있을 겁니다사용.#define
최대 길이(이유는 2단계 참조):
std::string buffer;
buffer.resize(MAX_TOKEN_LENGTH);
- 사용하다
scanf
"width modifier"를 사용하여 스캔한 문자열의 크기를 제한하고 반환 값(반환 값은 스캔한 토큰의 수)을 확인하는 동안:
#define XSTR(__x) STR(__x)
#define STR(__x) #x
...
int rv = scanf("%" XSTR(MAX_TOKEN_LENGTH) "s", &buffer[0]);
- 안전한 방법으로 관리되는 문자열 크기를 실제 크기로 재설정합니다.
buffer.resize(strnlen(buffer.data(), MAX_TOKEN_LENGTH));
아래 토막글이 작동합니다.
string s(100, '\0');
scanf("%s", s.c_str());
길이 제한이 없는 버전(입력 길이를 알 수 없는 경우)입니다.
std::string read_string() {
std::string s; unsigned int uc; int c;
// ASCII code of space is 32, and all code less or equal than 32 are invisible.
// For EOF, a negative, will be large than 32 after unsigned conversion
while ((uc = (unsigned int)getchar()) <= 32u);
if (uc < 256u) s.push_back((char)uc);
while ((c = getchar()) > 32) s.push_back((char)c);
return s;
}
성능을 고려하여,getchar
보다 확실히 더 빠릅니다.scanf
, 그리고 std::string::reserve는 버퍼를 미리 allocate하여 잦은 재할당을 방지할 수 있습니다.
적절한 크기의 std:: 문자열을 구성하고 기본 문자 저장소로 읽을 수 있습니다.
std::string str(100, ' ');
scanf("%100s", &str[0]);
str.resize(strlen(str.c_str()));
str.resize()에 대한 호출이 중요합니다. 그렇지 않으면 std::string 개체의 길이가 업데이트되지 않습니다.이것을 지적해주신 다니엘 트러그먼씨께 감사드립니다.
(문자열에 예약된 크기와 전달된 너비 간의 순서대로 오류는 없습니다.scanf
, 왜냐하면 C++11이기 때문에 std::string의 문자 데이터에 null 터미네이터가 뒤따르는 것이 보장되므로 크기+1 문자를 사용할 수 있습니다.)
int n=15; // you are going to scan no more than n symbols
std::string str(n+1); //you can't scan more than string contains minus 1
scanf("%s",str.begin()); // scanf only changes content of string like it's array
str=str.c_str() //make string normal, you'll have lots of problems without this string
언급URL : https://stackoverflow.com/questions/20165954/read-into-stdstring-using-scanf
'bestsource' 카테고리의 다른 글
EVOPdf, WebAPI 및 AngularJS를 사용하여 PDF 생성 (0) | 2023.11.05 |
---|---|
Mysql 8 원격 액세스 (0) | 2023.11.05 |
C# 기본적으로 1장으로 Excel 워크북 만들기 (0) | 2023.11.05 |
Woocommerce에서 후크를 통해 루프 제품 이미지 사용자 정의 (0) | 2023.11.05 |
소켓 옵션이 리스닝 소켓에서 수락()을 통해 상속됩니까? (0) | 2023.11.05 |