C/C++ 中帶空格字符串輸入的一些小trick

今天在重溫 C++ 的時候發現本身存在的一些問題,特此記錄下來。html

咱們能夠看一下下面這段代碼:ios

#include <iostream>
#include <cstdio>
#include <string>
#include <cctype>
using namespace std;
int main(int argc, char const *argv[])
{
	string s;
  cin >> s;
	int cnt[26]={0};//字母統計次數
	for(int i = 0; i < s.length(); i++){
		char c = s[i];
		if(isalpha(c)){
			cnt[toupper(c) - 'A'] ++;
		}
	}
	for(int i = 0; i < 26; i++){
		if(cnt[i] != 0){
			cout << char(i + 'A') << ": " << cnt[i] <<endl;
		}
	}
	return 0;
}

當咱們輸入字符串 Hello World! 時,結果會是多少呢?c++

apple@localhost  ~/Desktop/cpp_code  g++ run.cpp -o run.out -std=c++11 -O2
apple@localhost  ~/Desktop/cpp_code  ./run.out
Hello World!
E: 1
H: 1
L: 2
O: 1

上面這段代碼並不能很好的統計字符串中每一個英文字母在其中的出現頻率,我苦思冥想了許久,才發現了一個曾經忽略過的一個問題,cin 標準輸入字符串在遇到空格時候將會被截斷,而咱們須要對輸入一個帶空格的字符串進行特殊處理,而使用 getline 能夠完美的解決該問題。getline(std::cin, std::string) 在輸入回車符號時纔會被截斷,把上述代碼的輸入作一些調整就能夠完美的解決問題。shell

ps: 這種方法是針對 string 類編程

#include <iostream>
#include <cstdio>
#include <string>
#include <cctype>
using namespace std;
int main(int argc, char const *argv[])
{
	string s;
	getline(cin, s);
	int cnt[26]={0};//字母統計次數
	for(int i = 0; i < s.length(); i++){
		char c = s[i];
		if(isalpha(c)){
			cnt[toupper(c) - 'A'] ++;
		}
	}
	for(int i = 0; i < 26; i++){
		if(cnt[i] != 0){
			cout << char(i + 'A') << ": " << cnt[i] <<endl;
		}
	}
	return 0;
}

當咱們再次輸入字符串 Hello World! 時,結果又會是多少呢?數組

apple@localhost  ~/Desktop/cpp_code  g++ run.cpp -o run.out -std=c++11 -O2
apple@localhost  ~/Desktop/cpp_code  ./run.out
Hello World!
D: 1
E: 1
H: 1
L: 3
O: 2
R: 1
W: 1

這就很OK了!app

除此以外,還有沒有其餘方法能夠輸入帶空格的字符串呢?函數

答案是有的,如下我將全部可能出現的狀況一一列舉出來。spa

情景一:已知輸入的字符串序列c++11

針對這種狀況,咱們能夠直接在定義的時候輸入字符串序列便可,例如咱們已知咱們要輸入的字符串序列爲 Hello World! ,咱們能夠寫出以下定義:

str = "Hello World!";

情景二:輸入字符串序列未知,可是知道字符串序列的最大長度範圍

方法一:

按照上述所給的 getline 函數,咱們能夠經過以下調用方法:

cin.getline(str, len);

第一個參數 str 用來存儲輸入行的數組名稱,第二個參數是要讀取的字符數。

方法二:

咱們能夠使用字符數組的方式去解決這個問題,這個時候咱們天然會想到 get 方法,調用方式以下:

cin.get(str, len);

和方法一同樣,二者都是讀取一行輸入,直至換行符,而二者的不一樣在於 getline 將換行符丟棄,而 get() 將換行符保留在輸入序列裏,因而咱們會考慮以下改寫方式:

while((c=cin.get())!='\n')

而如果採用 C 語言函數庫中的辦法,咱們又應該如何去表示呢?

方法三:

C語言中輸入一個字符串,咱們首先想到的就是使用 scanf 函數,但 scanf 默認回車和空格是輸入不一樣組之間的間隔和結束符號,因此輸入帶空格,tab或者回車的字符串是不能夠的,咱們能夠利用格式符 「%[]」 。它的做用爲掃描字符集合,調用方式以下:

scanf("%[^c]", str);

其中 「c」 是一個具體的字符常量(包括控制字符)。當輸入字符串時,字符 「c」 將被看成當前輸入的結束符。利用此格式符就能夠由編程者本身指定一個輸入結束符。

方法四:

C語言中還有一種輸入字符串的方式,即便用 gets 函數。gets函數是以回車做爲結束符,調用方式以下:

char str[length]; 
gets(str);

其中 length 是字符串序列最大的長度範圍,是一個具體的數值。

情景三:輸入字符串序列未知,且字符串序列的最大長度範圍也未知

針對這種 string 類問題,這個時候咱們只有採用 getline 函數去解決了,調用方式以下:

getline(cin, s);

原文出處:https://www.cnblogs.com/ECJTUACM-873284962/p/11619496.html

相關文章
相關標籤/搜索