C++ 等效于 C fgets

标签 c++ c

我正在寻找与 C fgets 等效的 C++ fstream 函数。我尝试使用 fstream 的 get 函数,但没有得到我想要的。 get 函数不提取 delim 字符,而 fgets 函数用于提取它。所以,我写了一个代码来从我的代码本身插入这个 delim 字符。但它给出了奇怪的行为。请在下面查看我的示例代码;

#include <stdio.h>
#include <fstream>
#include <iostream>

int main(int argc, char **argv)
{
    char str[256];
    int len = 10;
    std::cout << "Using C fgets function" << std::endl;
    FILE * file = fopen("C:\\cpp\\write.txt", "r");
    if(file == NULL){
      std::cout << " Error opening file" << std::endl;
    }
    int count = 0;
    while(!feof(file)){
        char *result = fgets(str, len, file);
        std::cout << result << std::endl ;
        count++;
    }
    std::cout << "\nCount = " << count << std::endl;
    fclose(file);


std::fstream fp("C:\\cpp\\write.txt", std::ios_base::in);
int iter_count = 0; 
 while(!fp.eof() && iter_count < 10){

    fp.get(str, len,'\n');
    int count = fp.gcount();
    std::cout << "\nCurrent Count = " << count << std::endl;
    if(count == 0){
        //only new line character encountered
        //adding newline character
        str[1] = '\0';
        str[0] = '\n';
        fp.ignore(1, '\n');
        //std::cout << fp.get(); //ignore new line character from stream
    }
    else if(count != (len -1) ){

         //adding newline character
        str[count + 1] = '\0';
        str[count ] = '\n';
        //std::cout << fp.get(); //ignore new line character from stream
        fp.ignore(1, '\n');
        //std::cout << "Adding new line \n";
    }       

    std::cout << str  << std::endl;
    std::cout << " Stream State : Good: " << fp.good() << " Fail: " << fp.fail() << std::endl;

    iter_count++;
}
std::cout << "\nCount = " << iter_count <<  std::endl;
fp.close();


return 0;

我使用的txt文件是write.txt,内容如下:

This is a new lines.
Now writing second
line
DONE

如果您观察我的程序,我会先使用 fgets 函数,然后对同一个文件使用 get 函数。在 get 函数的情况下,流状态变坏。

谁能指出这里出了什么问题?

更新:我现在发布了一个最简单的代码,但在我这边不起作用。如果我现在不关心 delim 字符,只是使用 getline 一次读取整个文件 10 个字符:

void read_file_getline_no_insert(){
    char str[256];
    int len =10;
    std::cout << "\nREAD_GETLINE_NO_INSERT FUNCITON\n" << std::endl;
    std::fstream fp("C:\\cpp\\write.txt", std::ios_base::in);
    int iter_count = 0; 
     while(!fp.eof() && iter_count < 10){

        fp.getline(str, len,'\n');
        int count = fp.gcount();
        std::cout << "\nCurrent Count = " << count << std::endl;
        std::cout << str  << std::endl;
        std::cout << " Stream State : Good: " << fp.good() << " Fail: " << fp.fail() << std::endl;   
        iter_count++;
    }
    std::cout << "\nCount = " << iter_count <<  std::endl;
    fp.close();

}
int main(int argc, char **argv)
{

    read_file_getline_no_insert();  

    return 0;
}

如果我们看到上面代码的输出:

READ_GETLINE_NO_INSERT FUNCITON

Current Count = 9
This is a
 Stream State : Good: 0 Fail: 1

Current Count = 0

 Stream State : Good: 0 Fail: 1

您会看到流的状态变为 Bad 并且设置了失败位。我无法理解这种行为。

Rgds 沙巴

最佳答案

std::getline() 将从流中读取字符串,直到遇到分隔符(默认为换行符)。

fgets() 不同,std::getline() 丢弃定界符。但是,与 fgets() 不同的是,它将读取整行(如果可用内存允许),因为它使用 std::string 而不是 char * 。这使得它在实践中更容易使用。

所有派生自 std::istream(它是所有输入流的基类)的类型也有一个名为 getline() 的成员函数像 fgets() - 接受一个 char * 和一个缓冲区大小。尽管如此,它仍然会丢弃分隔符。

特定于 C++ 的选项是重载函数(即在多个版本中可用),因此您需要阅读文档以确定哪一个适合您的需要。

关于C++ 等效于 C fgets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28911403/

相关文章:

c++ - cocos2dx C++ 循环遍历 cocos2d::Vector

c++ - 这个二维数组初始化是个坏主意吗?

c - 从 c 中的用户输入中读取 2 个整数

c - 简单的 Rand() 函数

c - 如何在没有得到编译警告的情况下表达 wait(NULL)?

c++ - 这是糟糕的代码吗?

c++ - GNU Gettext 和宽字符

c++ - 如何使用代码块 Ubuntu 编译 64 位 C++ 程序

c - 使用 execlp 的更多过滤器参数

java - 动态生成变量名