关于cin.getline()

cin.getline()解析
本文通过对比两个示例代码,详细解析了C++中cin.getline()函数的工作原理及其与cin.gcount()的关系,揭示了当输入达到指定长度时,函数如何处理换行符及字符计数。

      在网上查过关于cin.getline()用法之类的文章,也翻阅过不少有关I/O的书籍,我便认为已深刻认识了cin.getline(),但一次意外的使用却使我百思不得其解,请看以下两段代码。

 

代码1:
 void main()
{
   
char a[10
];
    cin.getline(a,
10);//输入"123456789"

    cout << a<< endl; //输出"123456789"
    cout << cin.gcount(); //输出10
}


代码2:

 

void main()
{
   
char a[10
];
    cin.getline(a,
10);//输入"1234567890"

    cout << a<< endl; //输出"123456789"
    cout << cin.gcount(); //输出9
}

 

      为什么两次输入得到的cin.gcount()结果会不同?在多次试验与假设中,我或许得到了正确的解释。

      首先,我们要注意一下,其实cin.getline(a,10)还有一个默认参数,只是隐藏了而已,它就是输入的边界符,默认为'/n'。那么,我把它的真面目还原一下,即cin.getline(a,10,'/n')。

       然后,我们再看看cin.getline(a,10,'/n')是如何运作的,我看过的一些书上说cin.getline()会把'/n'给丢弃。

      事实上,在cin.getline()的第二个参数的范围内,如果输入了'/n','/n'会先从缓冲区中被接收(或读取),然后再被丢弃。而cin.gcount()的作用是输出从输入流中被读取的字符数(或字节数),所以在代码1中cin.gcount()会输出10,即使'/n'已被cin.getline()所丢弃,但'/n'的确被读取了(从缓冲区已找不到'/n'的影子)。如果你要问“你怎么知道啊?”,我会回答:“是cin.gcount()告诉我的!”正如代码1,输入“123456789”,它不会像cin.get(a,10)那样输出9,而是输出10。

      那么,代码二的cout << cin.gcount()为什么会输出9呢?这是因为在cin.getline()的第二个参数的范围内,并没遇到'/n',故只接收前9个可视字符,后再自动补加一个'/0'.

 

 

证明

 

代码3:
void main()
{
   
char a[10
];
    cin.getline(a,
10,'0');//输入"1234567890"

    cout << a<< endl; //输出"123456789"
    cout << cin.gcount(); //输出10

}

PS:由于istream的成员函数都被封装起来,所以无法确认是否真的如此,加上在MSDN上对cin.getline()也没详细的分析内部原理,故写此文章来大胆猜测一下。以上代码均通过VC6.0,如有知道cin.getline()的内部实现的,恳请指教!

### 关于 `cin.getline` 的用法及常见问题 #### 定义与基本语法 `cin.getline()` 是 C++ 中用于从标准输入流读取字符串的一种方法。它能够读取包含空格的整行数据,直到遇到指定的终止符或达到最大长度为止[^1]。 其基本语法如下: ```cpp istream& getline (char* s, streamsize n); istream& getline (char* s, streamsize n, char delim); ``` - 参数说明: - `s`: 存储输入的字符数组。 - `n`: 表示最多可存储的字符数量(包括结尾的 `\0`),实际有效字符数为 `n-1`。 - `delim`: 可选参数,默认为换行符 (`&#39;\n&#39;`),表示终止符。 当调用不带第三个参数的形式时,程序会默认以换行符作为终止条件[^2]。 #### 使用示例 下面是一个简单的例子展示如何使用 `cin.getline()` 来获取用户输入的一行文字: ```cpp #include <iostream> using namespace std; int main() { const int MAX_LEN = 100; char buffer[MAX_LEN]; cout << "请输入一行文本:" << endl; cin.getline(buffer, MAX_LEN); cout << "您输入的内容是:" << buffer << endl; return 0; } ``` 此代码片段定义了一个大小固定的字符数组来保存用户的输入,并通过 `cin.getline()` 方法捕获整个行的数据[^3]。 #### 常见问题分析 ##### 输入缓冲区溢出 如果输入的字符数目超过了设定的最大长度,则会发生截断现象,即只保留前 `(n-1)` 个字符并自动附加一个 null 终止符(`\0`)。此外,在这种情况下可能会引发未定义行为或者后续操作失败的情况[^3]。 解决方案之一是在设计阶段合理评估所需空间需求;另一个办法则是利用异常机制检测此类错误的发生。 ##### 处理多余空白字符 由于 `cin.getline()` 默认不会跳过前置空白字符(如空格),所以在某些场景下可能需要额外清理这些不必要的部分[^1]。 可以通过手动清除输入队列中的残留项实现这一点: ```cpp std::cin.ignore(std::numeric_limits<std::streamsize>::max(), &#39;\n&#39;); ``` 这段语句的作用是从当前输入流中移除所有直至下一个新行之前的元素,从而避免潜在干扰[^2]。 #### 总结 综上所述,掌握好 `cin.getline()` 的正确运用对于编写健壮可靠的 C++ 应用至关重要。理解它的功能边界以及应对可能出现的各种状况有助于提升编程效率和质量。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值