亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索

c++如何將字符串轉(zhuǎn)換為整數(shù)_c++字符串轉(zhuǎn)整數(shù)常用方法匯總

裘德小鎮(zhèn)的故事
發(fā)布: 2025-10-16 20:49:02
原創(chuàng)
127人瀏覽過
C++中字符串轉(zhuǎn)整數(shù)推薦使用std::stoi,因其支持異常處理和部分轉(zhuǎn)換檢測;std::istringstream適用于解析含多個數(shù)值或復(fù)雜格式的字符串;atoi和sscanf雖性能略優(yōu)但缺乏安全機(jī)制,不推薦用于現(xiàn)代C++。

c++如何將字符串轉(zhuǎn)換為整數(shù)_c++字符串轉(zhuǎn)整數(shù)常用方法匯總

在C++中將字符串轉(zhuǎn)換為整數(shù),主要有幾種方法,每種都有其適用場景和特點(diǎn)。最推薦且現(xiàn)代C++風(fēng)格的是使用std::stoi,它不僅簡潔,還提供了良好的錯誤處理機(jī)制。此外,std::istringstream提供了更靈活的流式解析能力,而C風(fēng)格的atoisscanf在特定場景下也有其用武之地,但通常伴隨著更多的風(fēng)險。選擇哪種方法,往往需要權(quán)衡安全性、便利性和對錯誤的容忍度。

解決方案

將C++字符串轉(zhuǎn)換為整數(shù),我們可以從幾個不同的角度入手,每種方法都有其獨(dú)特的哲學(xué)和實(shí)踐考量。

1. 使用 std::stoi (C++11及更高版本)

這是現(xiàn)代C++中最推薦的方法。std::stoi 函數(shù)位于 <string> 頭文件中,它能夠?qū)?std::string 對象轉(zhuǎn)換為 int。它的強(qiáng)大之處在于提供了異常機(jī)制來處理無效輸入或超出范圍的數(shù)值。

立即學(xué)習(xí)C++免費(fèi)學(xué)習(xí)筆記(深入)”;

#include <iostream>
#include <string>
#include <stdexcept> // For std::invalid_argument, std::out_of_range

// 示例:將字符串 "123" 轉(zhuǎn)換為整數(shù)
std::string str1 = "123";
try {
    int num1 = std::stoi(str1);
    std::cout << "stoi(\"" << str1 << "\"): " << num1 << std::endl; // 輸出: 123
} catch (const std::invalid_argument& e) {
    std::cerr << "無效參數(shù): " << e.what() << std::endl;
} catch (const std::out_of_range& e) {
    std::cerr << "超出范圍: " << e.what() << std::endl;
}

// 示例:包含非數(shù)字字符的字符串
std::string str2 = "123abc";
try {
    // stoi 會嘗試轉(zhuǎn)換開頭的數(shù)字部分,并返回轉(zhuǎn)換后的值
    // 如果需要嚴(yán)格檢查整個字符串,可以結(jié)合第二個參數(shù)pos
    size_t pos;
    int num2 = std::stoi(str2, &pos);
    std::cout << "stoi(\"" << str2 << "\"): " << num2 << std::endl; // 輸出: 123
    if (pos != str2.length()) {
        std::cout << "注意: 字符串 \"" << str2 << "\" 在位置 " << pos << " 之后包含非數(shù)字字符。" << std::endl;
    }
} catch (const std::invalid_argument& e) {
    std::cerr << "無效參數(shù): " << e.what() << std::endl;
} catch (const std::out_of_range& e) {
    std::cerr << "超出范圍: " << e.what() << std::endl;
}

// 示例:完全非數(shù)字的字符串
std::string str3 = "hello";
try {
    int num3 = std::stoi(str3); // 會拋出 std::invalid_argument
    std::cout << "stoi(\"" << str3 << "\"): " << num3 << std::endl;
} catch (const std::invalid_argument& e) {
    std::cerr << "無效參數(shù) (預(yù)期): " << e.what() << std::endl; // 輸出: 無效參數(shù) (預(yù)期): stoi
} catch (const std::out_of_range& e) {
    std::cerr << "超出范圍: " << e.what() << std::endl;
}

// 示例:超出 int 范圍的字符串
std::string str4 = "2147483648"; // 2^31, 超過 int 最大值 (通常是 2147483647)
try {
    int num4 = std::stoi(str4); // 會拋出 std::out_of_range
    std::cout << "stoi(\"" << str4 << "\"): " << num4 << std::endl;
} catch (const std::invalid_argument& e) {
    std::cerr << "無效參數(shù): " << e.what() << std::endl;
} catch (const std::out_of_range& e) {
    std::cerr << "超出范圍 (預(yù)期): " << e.what() << std::endl; // 輸出: 超出范圍 (預(yù)期): stoi
}
登錄后復(fù)制

std::stoi 的第二個可選參數(shù) std::istringstream0 是一個 std::istringstream1 指針,用于存儲轉(zhuǎn)換結(jié)束時字符串中下一個字符的索引。這對于檢查字符串是否完全由數(shù)字組成非常有用。

2. 使用 std::istringstream

std::istringstream 是一個基于字符串的輸入流,它提供了類似于 std::istringstream4 的功能,可以從字符串中提取各種類型的數(shù)據(jù)。這在處理更復(fù)雜的字符串解析任務(wù)時非常靈活。

#include <iostream>
#include <string>
#include <sstream> // For std::istringstream

std::string str = "456";
int num;
std::istringstream iss(str);
iss >> num;

if (iss.fail()) { // 檢查轉(zhuǎn)換是否失敗
    std::cerr << "istringstream 轉(zhuǎn)換失敗。" << std::endl;
} else {
    std::cout << "istringstream(\"" << str << "\"): " << num << std::endl; // 輸出: 456
}

// 示例:處理帶非數(shù)字字符的字符串
std::string str_bad = "789abc";
int num_bad;
std::istringstream iss_bad(str_bad);
iss_bad >> num_bad;

if (iss_bad.fail()) {
    std::cerr << "istringstream 轉(zhuǎn)換失敗,可能包含非數(shù)字字符或格式不正確。" << std::endl;
} else {
    std::cout << "istringstream(\"" << str_bad << "\"): " << num_bad << std::endl; // 輸出: 789
    // 同樣,如果需要嚴(yán)格檢查,可以檢查流中是否還有剩余字符
    char remaining_char;
    if (iss_bad >> remaining_char) {
        std::cout << "注意: 字符串 \"" << str_bad << "\" 轉(zhuǎn)換后還有剩余字符。" << std::endl;
    }
}
登錄后復(fù)制

std::istringstream 的優(yōu)點(diǎn)在于其通用性,不僅可以轉(zhuǎn)換為 int,還可以轉(zhuǎn)換為 std::istringstream7、std::istringstream8 或其他自定義類型。通過檢查 std::istringstream9 或 atoi0 可以判斷轉(zhuǎn)換是否成功。

3. 使用 atoi (C風(fēng)格函數(shù))

atoi (ASCII to integer) 是一個C風(fēng)格的函數(shù),位于 atoi3 頭文件中。它將C風(fēng)格字符串(atoi4)轉(zhuǎn)換為 int。

#include <iostream>
#include <string>
#include <cstdlib> // For atoi

std::string str_c = "789";
int num_c = std::atoi(str_c.c_str()); // 需要轉(zhuǎn)換為 C 風(fēng)格字符串
std::cout << "atoi(\"" << str_c << "\"): " << num_c << std::endl; // 輸出: 789

// 示例:包含非數(shù)字字符的字符串
std::string str_c_bad = "123xyz";
int num_c_bad = std::atoi(str_c_bad.c_str());
std::cout << "atoi(\"" << str_c_bad << "\"): " << num_c_bad << std::endl; // 輸出: 123

// 示例:完全非數(shù)字的字符串
std::string str_c_invalid = "hello";
int num_c_invalid = std::atoi(str_c_invalid.c_str());
std::cout << "atoi(\"" << str_c_invalid << "\"): " << num_c_invalid << std::endl; // 輸出: 0
登錄后復(fù)制

atoi 的主要缺點(diǎn)是它不提供任何錯誤檢查機(jī)制。如果字符串無法轉(zhuǎn)換為有效的整數(shù),它會返回 atoi7,但這與字符串本身就是 "0" 的情況無法區(qū)分。此外,如果轉(zhuǎn)換結(jié)果超出 int 的表示范圍,atoi 的行為是未定義的。因此,在需要健壯錯誤處理的現(xiàn)代C++代碼中,通常不推薦使用 atoi。

4. 使用 sscanf (C風(fēng)格函數(shù))

sscanf 也是一個C風(fēng)格函數(shù),位于 sscanf3 頭文件中,它從字符串中讀取格式化的數(shù)據(jù)。

#include <iostream>
#include <string>
#include <cstdio> // For sscanf

std::string str_s = "101";
int num_s;
int result = std::sscanf(str_s.c_str(), "%d", &num_s);

if (result == 1) { // 檢查是否成功匹配了一個項
    std::cout << "sscanf(\"" << str_s << "\"): " << num_s << std::endl; // 輸出: 101
} else {
    std::cerr << "sscanf 轉(zhuǎn)換失敗。" << std::endl;
}

// 示例:包含非數(shù)字字符的字符串
std::string str_s_bad = "202abc";
int num_s_bad;
result = std::sscanf(str_s_bad.c_str(), "%d", &num_s_bad);
if (result == 1) {
    std::cout << "sscanf(\"" << str_s_bad << "\"): " << num_s_bad << std::endl; // 輸出: 202
    // sscanf 也會在遇到非數(shù)字字符時停止,需要額外檢查字符串是否完全轉(zhuǎn)換
} else {
    std::cerr << "sscanf 轉(zhuǎn)換失敗。" << std::endl;
}
登錄后復(fù)制

sscanfatoi 提供了更精細(xì)的控制和錯誤報告(通過返回值),但它仍然是C風(fēng)格的,不如 std::stoistd::istringstream 那樣與C++的類型系統(tǒng)和異常機(jī)制融合得好。

怪獸AI數(shù)字人
怪獸AI數(shù)字人

數(shù)字人短視頻創(chuàng)作,數(shù)字人直播,實(shí)時驅(qū)動數(shù)字人

怪獸AI數(shù)字人44
查看詳情 怪獸AI數(shù)字人

std::stoi 在處理錯誤時有哪些優(yōu)勢?

std::stoi 在C++字符串轉(zhuǎn)整數(shù)的方法中,其錯誤處理能力是其最顯著的優(yōu)勢,這讓它在現(xiàn)代C++編程中成為首選。它的優(yōu)勢主要體現(xiàn)在兩個方面:

首先,異常機(jī)制。std::stoi 在遇到無法轉(zhuǎn)換的字符串(如 "hello")時,會拋出 std::stoi1 異常。而當(dāng)轉(zhuǎn)換結(jié)果超出 int 類型所能表示的范圍(溢出或下溢)時,它會拋出 std::stoi3 異常。這種基于異常的錯誤報告機(jī)制,與C++的異常處理流程完美契合,使得程序能夠清晰地捕獲并處理這些非正常情況,而不是默默地返回一個可能被誤解的錯誤值(比如 atoi 返回 atoi7)。

例如,考慮這樣的場景:你從用戶輸入或配置文件中讀取一個字符串,期望它是一個整數(shù)。如果用戶不小心輸入了 "ten" 或者一個天文數(shù)字,std::stoi 會立即通過異常告知你問題所在,你可以據(jù)此給用戶友好的提示,或者采取其他恢復(fù)措施。如果使用 atoi,"ten" 會被轉(zhuǎn)換為 atoi7,而 "0" 也是一個合法的整數(shù),這就會導(dǎo)致邏輯上的混淆,難以判斷是用戶真的輸入了 atoi7 還是輸入了無效字符。

其次,部分轉(zhuǎn)換的精確控制std::stoi 提供了可選的 std::stoi1 參數(shù)。這個參數(shù)能夠指示字符串中哪個位置停止了轉(zhuǎn)換。這意味著,即使字符串是 "123abc",std::stoi 也能告訴你它成功轉(zhuǎn)換了 "123",并且在索引 std::stoi3 處遇到了非數(shù)字字符 'a'。這對于需要解析混合了數(shù)字和非數(shù)字內(nèi)容的字符串非常有用,你可以根據(jù) std::istringstream0 的值來判斷整個字符串是否都被成功解析,或者哪些部分是有效的數(shù)字。

#include <iostream>
#include <string>
#include <stdexcept>

void convertAndCheck(const std::string& s) {
    try {
        size_t pos;
        int value = std::stoi(s, &pos);
        std::cout << "字符串: \"" << s << "\", 轉(zhuǎn)換為整數(shù): " << value << std::endl;
        if (pos < s.length()) {
            std::cout << "注意: 字符串在位置 " << pos << " 之后還有非數(shù)字字符: \"" << s.substr(pos) << "\"" << std::endl;
        }
    } catch (const std::invalid_argument& e) {
        std::cerr << "錯誤: 無效輸入 - \"" << s << "\" 無法轉(zhuǎn)換為整數(shù)。詳情: " << e.what() << std::endl;
    } catch (const std::out_of_range& e) {
        std::cerr << "錯誤: 數(shù)值超出范圍 - \"" << s << "\" 太大或太小。詳情: " << e.what() << std::endl;
    }
    std::cout << "------------------------" << std::endl;
}

// 調(diào)用示例
// convertAndCheck("123");
// convertAndCheck("-45");
// convertAndCheck("0");
// convertAndCheck("  99  "); // 會忽略前導(dǎo)和尾隨空格
// convertAndCheck("123test");
// convertAndCheck("test123"); // 拋出 invalid_argument
// convertAndCheck("2147483648"); // 拋出 out_of_range (假設(shè) int 為 32 位)
// convertAndCheck("-2147483649"); // 拋出 out_of_range
登錄后復(fù)制

總的來說,std::stoi 通過明確的異常類型和靈活的 std::istringstream0 參數(shù),提供了一種安全、可控且符合現(xiàn)代C++編程范式的字符串到整數(shù)轉(zhuǎn)換方案,極大地提升了代碼的健壯性和可維護(hù)性。

std::istringstream 適用于哪些更復(fù)雜的場景?

std::istringstream 的強(qiáng)大之處在于它模擬了一個輸入流,這意味著它不僅能做簡單的字符串到整數(shù)轉(zhuǎn)換,還能處理更復(fù)雜、更像自然語言的解析任務(wù)。把它想象成一個可以從內(nèi)存中的字符串讀取數(shù)據(jù)的 std::istringstream4,這樣它的應(yīng)用場景就一下子開闊了。

1. 解析包含多個數(shù)值或不同類型數(shù)據(jù)的字符串: 如果你的字符串不僅僅是一個數(shù)字,而是像 "Width: 100 Height: 200 Depth: 50" 這樣的格式,或者 "Point(10, 20)",std::istringstream 就能輕松應(yīng)對。你可以像從文件中讀取數(shù)據(jù)一樣,使用 <string>1 運(yùn)算符連續(xù)提取數(shù)據(jù)。

#include <iostream>
#include <string>
#include <sstream>

std::string configLine = "Resolution: 1920x1080 RefreshRate: 144Hz";
std::istringstream iss(configLine);
std::string label1, resolutionStr, label2, refreshRateStr;
int width, height, refreshRate;
char x_char; // 用于捕獲 'x'

// 嘗試解析 "Resolution: 1920x1080"
if (iss >> label1 && label1 == "Resolution:") {
    if (iss >> width >> x_char && x_char == 'x' && iss >> height) {
        std::cout << "解析到分辨率: " << width << "x" << height << std::endl;
    } else {
        std::cerr << "解析分辨率失敗。" << std::endl;
    }
} else {
    std::cerr << "未找到 Resolution 標(biāo)簽。" << std::endl;
}

// 嘗試解析 "RefreshRate: 144Hz"
if (iss >> label2 && label2 == "RefreshRate:") {
    // 這里可以使用字符串來讀取 "144Hz",然后進(jìn)一步處理
    // 或者直接嘗試讀取整數(shù),如果后面有非數(shù)字字符,流會進(jìn)入失敗狀態(tài)
    if (iss >> refreshRate) {
        std::cout << "解析到刷新率: " << refreshRate << "Hz" << std::endl;
        // 檢查是否有剩余字符,如 'Hz'
        std::string unit;
        iss >> unit; // 嘗試讀取單位
        if (!iss.fail() && unit == "Hz") {
            std::cout << "單位 'Hz' 也被成功識別。" << std::endl;
        }
    } else {
        std::cerr << "解析刷新率失敗。" << std::endl;
    }
} else {
    std::cerr << "未找到 RefreshRate 標(biāo)簽。" << std::endl;
}
登錄后復(fù)制

2. 靈活的錯誤檢查和狀態(tài)管理:std::istringstream 作為流,擁有 <string>3, <string>4, <string>5, <string>6 等方法來檢查流的狀態(tài)。這在解析復(fù)雜或格式不固定的字符串時非常有用。你可以根據(jù)流的狀態(tài)來判斷是數(shù)據(jù)格式不匹配、到達(dá)字符串末尾還是發(fā)生了更嚴(yán)重的錯誤。

3. 將字符串轉(zhuǎn)換為非基本類型: 如果你有自定義的類型,并且為其重載了 <string>7,那么 std::istringstream 也能無縫地將字符串內(nèi)容解析到你的自定義對象中。這使得它在處理序列化/反序列化任務(wù)時非常方便。

4. 避免字符串拷貝的性能考量 (雖然不總是最快,但概念上靈活): 雖然創(chuàng)建 std::istringstream 對象本身有開銷,但在某些場景下,如果需要對一個長字符串進(jìn)行多次不同模式的解析,或者需要逐詞、逐行地處理,使用流的方式可以避免反復(fù)創(chuàng)建子字符串或進(jìn)行其他字符串操作,從而在概念上提供一種更“流式”的、可能更高效的解析方式。

簡單來說,當(dāng)你的字符串不僅僅是一個裸數(shù)字,而是包含了結(jié)構(gòu)、分隔符、多個數(shù)據(jù)點(diǎn),或者需要進(jìn)行更細(xì)致的錯誤判斷和分步解析時,std::istringstream 就能大顯身手。它提供了一種面向?qū)ο蟮?、更C++化的字符串解析范式,讓代碼更具可讀性和擴(kuò)展性。

性能考量:在不同轉(zhuǎn)換方法間如何選擇?

在字符串到整數(shù)的轉(zhuǎn)換中,性能確實(shí)是一個值得探討的問題,但我們首先要明確,對于絕大多數(shù)應(yīng)用程序而言,代碼的清晰度、健壯性和正確性遠(yuǎn)比微小的性能差異更重要。只有在遇到性能瓶頸,并且分析表明字符串轉(zhuǎn)換是主要瓶CPU時間的地方,我們才需要深入研究性能。

1. std::stoi 通常,std::stoi 是一個經(jīng)過高度優(yōu)化的函數(shù)。它在內(nèi)部實(shí)現(xiàn)上會利用一些高效的字符處理技術(shù)。對于單次、直接的字符串到整數(shù)轉(zhuǎn)換,它的性能表現(xiàn)非常出色,并且由于其異常處理機(jī)制,它在安全性上提供了最好的平衡。它的開銷主要在于異常處理路徑,如果預(yù)期會有很多無效輸入導(dǎo)致頻繁拋出異常,這可能會有額外的性能成本。但對于大部分有效轉(zhuǎn)換,其性能是足夠快的。

2. std::istringstreamstd::istringstream 涉及到流對象的構(gòu)建、虛擬函數(shù)調(diào)用以及更復(fù)雜的內(nèi)部狀態(tài)管理,因此它的理論開銷通常會比 std::stoi 稍大。每次轉(zhuǎn)換都需要創(chuàng)建一個 std::string6 對象,這本身就是一種開銷。然而,這種開銷對于大多數(shù)應(yīng)用程序來說是微不足道的。它的優(yōu)勢在于解析復(fù)雜格式的字符串,如果你的任務(wù)是解析多個值或混合類型,那么 std::string6 的整體效率可能更高,因?yàn)樗苊饬硕啻蔚淖址蟹趾蛦为?dú)轉(zhuǎn)換。如果你需要從一個字符串中提取多個整數(shù),使用一個 std::string6 對象循環(huán)提取,其總性能可能優(yōu)于多次調(diào)用 std::stoi。

3. atoisscanfatoisscanf 是C風(fēng)格的函數(shù),它們通常被認(rèn)為在純粹的轉(zhuǎn)換速度上可能略快,因?yàn)樗鼈儾簧婕癈++的異常處理機(jī)制或流對象的開銷。atoi 是最簡單的,但它的嚴(yán)重缺點(diǎn)是沒有錯誤報告,這使得它在現(xiàn)代C++中幾乎不應(yīng)該被用于任何需要可靠性檢查的場景。sscanf 提供了更多的控制,其性能也通常不錯,但它需要C風(fēng)格的字符串 (atoi4),并且其錯誤處理通過返回值進(jìn)行,不如異常直觀。

如何選擇?

  • 首選 std::stoi 在大多數(shù)情況下,如果只需要將一個 std::string 轉(zhuǎn)換為一個整數(shù),并且需要健壯的錯誤處理(包括無效輸入和數(shù)值溢出),std::stoi 是最佳選擇。它的性能足夠好,并且提供了現(xiàn)代C++應(yīng)有的安全性。
  • 復(fù)雜解析選 std::istringstream 如果你需要從一個字符串中

以上就是c++++如何將字符串轉(zhuǎn)換為整數(shù)_c++字符串轉(zhuǎn)整數(shù)常用方法匯總的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!

c++速學(xué)教程(入門到精通)
c++速學(xué)教程(入門到精通)

c++怎么學(xué)習(xí)?c++怎么入門?c++在哪學(xué)?c++怎么學(xué)才快?不用擔(dān)心,這里為大家提供了c++速學(xué)教程(入門到精通),有需要的小伙伴保存下載就能學(xué)習(xí)啦!

下載
來源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn
最新問題
開源免費(fèi)商場系統(tǒng)廣告
熱門教程
更多>
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長!
關(guān)注服務(wù)號 技術(shù)交流群
PHP中文網(wǎng)訂閱號
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號