在C和c++中逐行读取

Line by line reading in C and C++?

本文关键字:逐行 读取 c++      更新时间:2023-10-16

我想在C或c++中逐行读取文件,当我假设一行的固定大小时,我知道如何做到这一点,但是是否有一种简单的方法可以以某种方式计算或获得文件中一行或所有行所需的确切大小?(如果有人能做到的话,一个字一个字地读到换行符对我也有好处。)

如果您使用流式阅读器,所有这些都将对您隐藏。参见getline。下面的例子是基于这里的代码。

// getline with strings
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
  string str;
  ifstream ifs("data.txt");
  getline (ifs,str);
  cout << "first line of the file is " << str << ".n";
}

在C中,如果您有POSIX 2008库(例如,最新版本的Linux),您可以使用POSIX getline()函数。如果你的库中没有这个函数,你可以很容易地实现它,这可能比你自己发明一个接口来完成这项工作要好。

在c++中,您可以使用std::getline()

尽管这两个函数具有相同的基本名称,但调用约定和语义却有很大的不同(因为C和c++语言有很大的不同)——当然,除了它们都从文件流中读取一行数据之外。

没有一种简单的方法来判断文件中最长的行有多大-除非读取整个文件来找出,这有点浪费。

我将使用IFStream和getline从文件中读取。

http://www.cplusplus.com/doc/tutorial/files/

int main () {
    string line;
    ifstream myfile ("example.txt");
    if (myfile.is_open())
    {
        while ( myfile.good() )
        {
            getline (myfile,line);
            cout << line << endl;
        }
        myfile.close();
    }
    else cout << "Unable to open file"; 
    return 0;
}

只有读入后才能得到行长度。但是,您可以反复读入缓冲区,直到到达行尾。

对于c语言编程,尝试使用fgets读取一行代码。它将读取n个字符,如果遇到换行符则停止。您可以在大小为n的小缓冲区中读取,直到字符串中的最后一个字符是换行符。

查看上面的链接了解更多信息。

下面是一个关于如何使用一个小缓冲区读取和显示整行文件的示例:

#include <stdio.h>
#include <string.h>
int main()
{
   FILE * pFile;
   const int n = 5;
   char mystring [n];
   int lineLength = 0;
   pFile = fopen ("myfile.txt" , "r");
   if (pFile == NULL) 
   {
       perror ("Error opening file");
   }
   else 
   {
        do 
        {
            fgets (mystring , n , pFile);
            puts (mystring);    
                    lineLength += strlen(mystring); 
        } while(mystring[strlen ( mystring)-1] != 'n' && !feof(pFile));
       fclose (pFile);
   }
   printf("Line Length: %dn", lineLength);
   return 0;
}

在c++中,您可以使用std::getline函数,它接受一个流并读取到第一个'n'字符。在C语言中,我会使用fgets并不断重新分配缓冲区,直到最后一个字符是'n',然后我们知道我们已经读取了整行。

c++:

std::ifstream file("myfile.txt");
std::string line;
std::getline(file, line);
std::cout << line;

C:

// I didn't test this code I just made it off the top of my head.
FILE* file = fopen("myfile.txt", "r");
size_t cap = 256;
size_t len = 0;
char* line = malloc(cap);
for (;;) {
    fgets(&line[len], cap - len, file);
    len = strlen(line);
    if (line[len-1] != 'n' && !feof(file)) {
        cap <<= 1;
        line = realloc(line, cap);
    } else {
        break;
    }
}
printf("%s", line);

getline只是POSIX,这里有一个ANSI (NO max-line-size信息需要!):

const char* getline(FILE *f,char **r)
{
  char t[100];
  if( feof(f) )
    return 0;
  **r=0;
  while( fgets(t,100,f) )
  {
    char *p=strchr(t,'n');
    if( p )
    {
      *p=0;
      if( (p=strchr(t,'r')) ) *p=0;
      *r=realloc(*r,strlen(*r)+1+strlen(t));
      strcat(*r,t);
      return *r;
    }
    else
    {
      if( (p=strchr(t,'r')) ) *p=0;
      *r=realloc(*r,strlen(*r)+1+strlen(t));
      strcat(*r,t);
    }
  }
  return feof(f)?(**r?*r:0):*r;
}

,现在在您的主目录中更简单和简短:

  char *line,*buffer = malloc(100);
  FILE *f=fopen("yourfile.txt","rb");
  if( !f ) return;
  setvbuf(f,0,_IOLBF,4096);
  while( (line=getline(f,&buffer)) )
    puts(line);
  fclose(f);
  free(buffer);

它适用于windows和Unix-textfiles,Unix for Unix AND Windows-textfiles

下面是使用std算法和迭代器的c++读行方法:

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
struct getline :
  public std::iterator<std::input_iterator_tag, std::string>
{
    std::istream* in;
    std::string line;
    getline(std::istream& in) : in(&in) {
        ++*this;
    }
    getline() : in(0) {
    }
    getline& operator++() {
        if(in && !std::getline(*in, line)) in = 0;
    }
    std::string operator*() const {
        return line;
    }
    bool operator!=(const getline& rhs) const {
        return !in != !rhs.in;
    }
};
int main() {
    std::vector<std::string> v;
    std::copy(getline(std::cin), getline(), std::back_inserter(v));
}