C++ 全局函数std::getline

本文介绍了C和C++中getline函数的功能与用法,包括标准C库中的getline扩展、C风格的fgets函数、C++标准库中的getline全局函数及不同输入流类的getline成员函数,并对比了它们之间的差异。
部署运行你感兴趣的模型镜像

经常会用到getline来读取文件,但是发现对于c和c++的getline之前没有一个很深入的认识,这里借鉴网上的一些资料总结一下。


1、在标准C语言中,getline函数是不存在的。在gcc编译器中,对标准c库进行了扩展,加入了一个getline函数。该函数的定义如下:

      
      #include <stdio.h>
      ssize_t getline(char **lineptr, size_t *n, FILE *stream);

2、标准C语言中虽然没有getline函数,但是有一个同样功能的fgets函数。fgets函数是c风格的按行读取的函数,读取时是读入换行符的,使用起来也还方便。c代码中建议使用此函数读取行。

3、c++标准库中全局函数getline。该函数定义如下:
     
   istream& getline ( istream& is, string& str, char delim );   
   istream& getline (istream& is, string& str);

函数说明详见:http://www.cplusplus.com/reference/string/string/getline/


c++标准库中有getline函数功能说明

从输入流读入一行到string s

•功能:
–从输入流中读入字符,存到string变量
–直到出现以下情况为止:
•读入了文件结束标志
•读到一个新行
–如果getline没有读入字符,将返回false,可用于判断文件是否结束

#include<iostream>  
#include<fstream>  
#include<string>  
  
using namespace std;  
  
int main()  
{  
    string buff;  
    ifstream infile;  
    ofstream outfile;  
    cout<<"Input file name: "<<endl;  
    cin>>buff;  
    infile.open(buff.c_str());  
  
    if(!infile)  
        cout<<"error"<<buff<<endl;  
      
    cout<<"Input outfile name: "<<endl;  
    cin>>buff;  
    outfile.open(buff.c_str());  
      
    while(getline(infile, buff))  
        outfile<<buff<<endl;  
  
    infile.close();  
    outfile.close();  
    return 0;  
  
}  

ios类实现了方法 operator void*() const;详细见:http://www.cplusplus.com/reference/ios/ios/operator_bool/ 

而所有的输入流类都是从ios类派生而来的,所以都有方法 operator void*() const。而getline返回的是istream对象,在while循环中需要将这个返回的istream对象转换为bool类型的值,所以这里编译器会调用operator void*() const来做一个隐式转换得到一个void*的指针。如果failebit或badbit是true的话,则返回NULL指针(即0值),转换为bool类型即为false;否则就转换为非NULL指针,对应bool类型即为true值。

getline在读到文件结束标志后就停止读了,如果再继续调用getline则会报错返回一个NULL指针,while循环就不会继续读了。即能达到读完文件后再读的话就报错的效果。

http://www.cplusplus.com/reference/ios/ios/operator_bool/      中附上的例子如下:

// evaluating a stream
#include <iostream>     // std::cerr
#include <fstream>      // std::ifstream

int main () {
  std::ifstream is;
  is.open ("test.txt");
  if (is) {
    // read file
  }
  else {
    std::cerr << "Error opening 'test.txt'\n";
  }
  return 0;
}

4、c++中不同的输入流类都定义了一个字函数getline,如std::istream::getline。但是这个子函数是c风格的,需要执行buffer的长度,当行的长度大于这个buffer长度时,状态位failbit设置为true了,getline读取就会出现问题。所以,不建议用输入流对象的子函数getline去读取行,而应该直接用c++的全局函数getline去读取行,简单好用,不用担心buffer长度的问题。


5、C++中读取一行的getline函数是不读入换行符的,而C语言中GCC编译器扩展的getline函数和fgets都是是读入换行符的。


总结:

按行读取文件就用c++全局函数std::getline吧,简单方便。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

#include <iostream> #include <fstream> #include <string> #include <cstdlib> #define MAX 1000 struct Person { std::string name; int price; std::string number; std::author; }; struct Arraybooks { struct Person book[MAX]; int length; }; void mean(); int outSystem(); void addBooks(Arraybooks* abs); void dalateBooks(Arraybooks* abs); int isExist(Arraybooks* abs, std::string name); void CheckBook(Arraybooks* abs); void cleanbooks(Arraybooks* abs); void showbooks(Arraybooks* abs); void changebooks(Arraybooks* abs); void saveBooks(Arraybooks* abs); void loadBooks(Arraybooks* abs); int main() { int x; Arraybooks abs; abs.length = 0; loadBooks(&abs); while (true) { mean(); std::cin >> x; switch (x) { case 1: addBooks(&abs); saveBooks(&abs); break; case 2: dalateBooks(&abs); saveBooks(&abs); break; case 3: CheckBook(&abs); break; case 4: cleanbooks(&abs); saveBooks(&abs); break; case 5: changebooks(&abs); saveBooks(&abs); break; case 6: showbooks(&abs); break; case 0: saveBooks(&abs); outSystem(); return 0; default: std::cout << "输入无效,请重新输入。" << std::endl; } } return 0; } void addBooks(Arraybooks* abs) { if (abs->length >= MAX) { std::cout << "书籍已满" << std::endl; } else { std::string name; std::cout << "请输入书籍的名字: " << std::endl; std::cin >> name; abs->book[abs->length].name = name; std::author; std::cout << "请输入书籍作者:" << std::end1; std::cin >> author; abs->book[abs->length].author = author; int price; std::cout << "请输入书的价格: " << std::endl; std::cin >> price; abs->book[abs->length].price = price; std::string num; std::cout << "请输入书的编号: " << std::endl; std::cin >> num; abs->book[abs->length].number = num; abs->length++; std::cout << "添加成功" << std::endl; } } int isExist(Arraybooks* abs, std::string name) { for (int i = 0; i < abs->length; ++i) { if (abs->book[i].name == name) { return i; } } return -1; } void dalateBooks(Arraybooks* abs) { std::cout << "请输入你要删除的书籍" << std::endl; std::string name; std::cin >> name; int ret = isExist(abs, name); if (ret != -1) { for (int i = ret; i < abs->length - 1; ++i) { abs->book[i] = abs->book[i + 1]; } abs->length--; std::cout << "删除成功" << std::endl; } else { std::cout << "查无此书" << std::endl; } } void CheckBook(Arraybooks* abs) { std::cout << "输入你要查找的书籍" << std::endl; std::string name; std::cin >> name; int ret = isExist(abs, name); if (ret != -1) { std::cout << "书名为:" << abs->book[ret].name << "\t"; std::cout << "书价格为:" << abs->book[ret].price << "\t"; std::cout << "书编号为:" << abs->book[ret].number << std::endl; } else { std::cout << "查无此书" << std::endl; } } void cleanbooks(Arraybooks* abs) { abs->length = 0; std::cout << "清理完成" << std::endl; } void changebooks(Arraybooks* abs) { std::cout << "输入你要修改的图书" << std::endl; std::string name; std::cin >> name; int ret = isExist(abs, name); if (ret != -1) { std::cout << "请输入名字: " << std::endl; std::string newName; std::cin >> newName; abs->book[ret].name = newName; std::cout << "请输入价格: " << std::endl; int price; std::cin >> price; abs->book[ret].price = price; std::cout << "请输入编号: " << std::endl; std::string num; std::cin >> num; abs->book[ret].number = num; std::cout << "修改成功" << std::endl; } else { std::cout << "查无此书" << std::endl; } } void showbooks(Arraybooks* abs) { if (abs->length == 0) { std::cout << "书架为空" << std::endl; } else { for (int i = 0; i < abs->length; ++i) { std::cout << "书籍名字 : " << abs->book[i].name << "\t"; std::cout << "书籍价格 : " << abs->book[i].price << "\t"; std::cout << "书籍编号 : " << abs->book[i].number << std::endl; } } } int outSystem() { std::cout << "欢迎下次使用" << std::endl; return 0; } void mean() { std::cout << "*************************" << std::endl; std::cout << "*******1、加入图书********" << std::endl; std::cout << "*******2、按名删除图书****" << std::endl; std::cout << "*******3、按名查找图书****" << std::endl; std::cout << "*******4、清空图书架******" << std::endl; std::cout << "*******5、修改图书名******" << std::endl; std::cout << "*******6、显示图书架******" << std::endl; std::cout << "*******0、退出系统********" << std::endl; std::cout << "*************************" << std::endl; } void saveBooks(Arraybooks* abs) { std::ofstream file("books.txt"); if (file.is_open()) { for (int i = 0; i < abs->length; ++i) { file << abs->book[i].name << "," << abs->book[i].price << "," << abs->book[i].number << std::endl; } file.close(); } else { std::cout << "无法打开文件保存图书信息。" << std::endl; } } void loadBooks(Arraybooks* abs) { std::ifstream file("books.txt"); if (file.is_open()) { std::string line; while (std::getline(file, line)) { size_t pos1 = line.find(','); size_t pos2 = line.find(',', pos1 + 1); if (pos1 != std::string::npos && pos2 != std::string::npos) { abs->book[abs->length].name = line.substr(0, pos1); abs->book[abs->length].price = atoi(line.substr(pos1 + 1, pos2 - pos1 - 1).c_str()); abs->book[abs->length].number = line.substr(pos2 + 1); abs->length++; } } file.close(); } }
最新发布
11-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值