Có nhiều cách kiểm tra chuỗi chỉ chứa chữ số (đại diện cho int). Dưới đây là các phương pháp từ cơ bản đến nâng cao.
Phương pháp 1: Dùng isdigit() - Kiểm tra từng ký tự
#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
bool isInteger(const char* str) {
if (!str || *str == '\0') return false;
// Cho phép dấu + hoặc - ở đầu
if (*str == '+' || *str == '-') str++;
if (*str == '\0') return false; // chỉ có dấu
while (*str) {
if (!isdigit(*str)) return false;
str++;
}
return true;
}
int main() {
char str[] = "3257fg";
cout << (isInteger(str) ? "Là số nguyên" : "KHÔNG phải số nguyên") << endl;
return 0;
}
Phương pháp 2: strtol() - Chuẩn C, an toàn và đầy đủ
#include <cstdlib>
#include <cerrno>
#include <climits>
bool isIntegerStrtol(const char* str, long* out = nullptr) {
if (!str || *str == '\0') return false;
char* endptr;
errno = 0;
long val = strtol(str, &endptr, 10);
// Kiểm tra: toàn bộ chuỗi được parse, không lỗi overflow
if (endptr == str) return false; // Không parse được ký tự nào
if (*endptr != '\0') return false; // Còn ký tự rác
if (errno == ERANGE) return false; // Overflow
if (out) *out = val;
return true;
}
Phương pháp 3: C++17 std::from_chars (Hiệu năng cao nhất)
#include <charconv>
#include <string_view>
bool isIntegerFromChars(std::string_view sv, int* out = nullptr) {
int value;
auto result = std::from_chars(sv.data(), sv.data() + sv.size(), value);
if (result.ec == std::errc() && result.ptr == sv.data() + sv.size()) {
if (out) *out = value;
return true;
}
return false;
}
Phương pháp 4: stringstream (C++98, dễ hiểu nhưng chậm)
#include <sstream>
#include <string>
bool isIntegerStringStream(const std::string& str, int* out = nullptr) {
std::stringstream ss(str);
int value;
char remaining;
if (ss >> value && !(ss >> remaining)) {
if (out) *out = value;
return true;
}
return false;
}
So sánh
| Phương pháp | Ưu điểm | Nhược điểm |
|---|---|---|
| isdigit() | Đơn giản, không thư viện thêm | Phải tự xử lý dấu, overflow |
| strtol() | Chuẩn C, xử lý dấu/overflow, trả về giá trị | C-style, cần errno |
| from_chars | Nhanh nhất, không allocation, không locale | C++17, không parse float |
| stringstream | Dễ hiểu, tự động trim whitespace | Chậm, heavy |
Khuyến nghị
- C++17+: Dùng
std::from_chars - C/C++ cũ: Dùng
strtol() - Cần parse + validate cùng lúc:
strtolhoặcfrom_chars