C ++의 문자열에서 비 인자를 제거합니다
-
03-07-2019 - |
문제
사람들이 쉼표를 정수에 입력하고 프로그램을 엉망으로 만드는 사람들에 대한 내 책에 통과 한 의견이 있었지만 정교하지는 않았습니다. 그것은 내가 생각하게 만들었습니다. 그래서 나는 std :: string을 취하고 모든 비 integer 문자를 제거하기 위해 작은 알고리즘을 작성하려고했습니다. 이 코드는 컴파일되지만 출력 이상으로 건너 뜁니다. 뉴스 스트링에 할당되지 않은 이유는 무엇입니까? if (isdigit (fstring [i]))가 숫자를 고정하기 위해 가리키는 주소에 대해 평가합니까?
//little algorithm to take the non-integers out of a string
//no idea on efficiency
#include <iostream>
#include <string>
int main()
{
std::cout << "Enter a number with non-integer characters: ";
std::string fstring;
getline(std::cin, fstring);
std::string newstring;
int i = 0, x = 0;
while (i != fstring.length())
{
if (isdigit(fstring[i]))
{
newstring[x] = fstring[i];
i++;
x++;
}
else
{
i++;
}
}
std::cout << std::endl;
std::cout << newstring;
system("PAUSE");
}
이 보조 질문은 아마도 다른 곳에 속한다 : 문자열을 int (또는 부동 소수점 번호)로 어떻게 변환합니까?
해결책
Newstring은 길이 0이므로 Newstring [x] 여기서 x = 0은 실제로 불법입니다. Newstring.append (1, fstring [i])를 사용하여 문자열에 추가해야합니다.
보조 질문은 atoi (), atof (), strtol (0, strtof () 함수를 찾으십시오.
다른 팁
문자열은 배열과 같지만 문자열의 기본 생성자는 빈 문자열을 만듭니다. 왜 필요한 것보다 더 많은 메모리를 할당해야합니까? 그렇지 않더라도 FSTRING의 필터링 된 사본에 충분히 커질 정도로 얼마나 큰지 말할 수 없습니다. 나는 그것이 충돌하지 않는다는 것에 깊은 인상을 받았다.
간단한 수정은 변경하는 것입니다.
std::string newstring;
에게:
std::string newstring(fstring.length(), '\0')
그리고 루프가 추가 된 후 :
newstring.resize(x);
이것은 그것을 보장 할 것입니다 newstring
여과 중에 충분한 공간 (아마도 더 많은 공간)이 있으며 필터링이 완료 될 때 적절한 크기로 줄어 듭니다. 당신은 또한 관심이있을 수 있습니다 std::remove_copy_if
기능 <algorithm>
.
예를 들어
struct isnotdigit { bool operator()(char c) { return !isdigit(c); } };
std::string newstring(fstring.length(), '\0');
std::string::iterator i = std::remove_copy_if(fstring.begin(),
fstring.end(), newstring.begin(), isnotdigit());
newstring.erase(i, newstring.end());
문자열을 정수 / 플로트로 변환하는 것 외에 atoi
, strtol
, atof
, strtof
, 등 등. 이미 언급 한 기능 ioStream 라이브러리를 사용할 수도 있습니다.
#include <sstream>
std::string integer("23");
std::istringstream iss(integer);
int result;
iss >> result;
std::string floatingpoint("3.14");
std::istringstream iss2(floatingpoint);
double result2;
iss2 >> result2;
또한 Printf 기능에 익숙하다면 관심이있을 수 있습니다. scanf
, sscanf
const char *s = "23";
int result;
sscanf(s, "%d", &result);
Shing Yip의 답변 확장 :
비 자격을 제거하려면 :
#include <iostream>
#include <functional>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string fstring;
getline(cin, fstring);
fstring.erase(
remove_if(fstring.begin(), fstring.end(),
not1(ptr_fun(static_cast<int(*)(int)>(isdigit)))
),
fstring.end()
);
cout << fstring << "\n";
}
그래도 왜 그 static_cast가 필요한지 잘 모르겠습니다. 나는 그것없이 Isdigit에 대해 모호하다고 생각합니다. [편집 : "네임 스페이스 STD 사용"을하지 않으면 필요하지 않으므로 게으른 글쓰기 예제 코드에 대한 내 잘못입니다.
이것이 자신의 루프를 굴리는 것보다 간단한 지 여부는 논란의 여지가 있습니다.
#include <iostream>
#include <string>
using namespace std;
int main() {
string fstring, ins;
getline(cin, ins);
for (string::iterator it = ins.begin(); it != ins.end(); ++it) {
if (isdigit(*it)) fstring.push_back(*it);
}
cout << fstring << "\n";
}
그리고 C ++ 0X는 기본적으로 우연히 제외 된 COPY_IF를 가지고 있으며, 구현하기가 사소합니다.
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
int main() {
std::string fstring, ins;
std::getline(std::cin, ins);
std::copy_if(ins.begin(), ins.end(),
std::back_inserter(fstring), isdigit);
std::cout << fstring << "\n";
}
int (또는 float)로 변환하려면 :
int i = boost::lexical_cast<int>(fstring);
또는 부스트가 없다면 :
#include <sstream>
int i = 0;
std::stringstream(fstring) >> i;
i를 초기화해야합니다. 그렇지 않으면 fstring이 비어 있으면 설정되지 않습니다.
숫자를 제거하려면 :
fstring.erase(
std::remove_if(fstring.begin(), fstring.end(), &isdigit),
fstring.end());
문자열을 int/float/로 변환하려면 ... :
int n1 = boost::lexical_cast<int>("123");
float n2 = boost::lexical_cast<float>("123.456");
- 플로팅 포인트 번호로 문자열 :
당신은 필요합니다 #include <cstdlib>
float strtof(const char *nptr, char **endptr);
예를 들어:
float f = strtof("3.4",NULL);
- 정수에 문자열
당신은 필요합니다 #include <cstdlib>
int atoi(const char *numPtr);
이것들은 c ++가 아닌 c- 함수이므로 c -string을 얻으려면 std :: string에서 c_str () 메소드를 사용해야합니다.
const char* c_str ( ) const;