【问题标题】:How to read a line from a text file in c/c++? [duplicate]如何从 C/C++ 中的文本文件中读取一行? [复制]
【发布时间】:2011-03-06 02:36:22
【问题描述】:

在进行了详尽的谷歌搜索并访问了许多论坛之后,我还没有为这个问题找到一个好的全面答案。很多论坛建议使用 get 行 istream& getline (char* s, streamsize n ) 函数。我的问题是,如果我不知道每行的长度是多少并且无法预测大小可能是什么?还有它在 C 中的等价物是什么?

c /c++ 中是否有任何特定函数可以每次从文本文件中读取一行?

说明,用 Code sn-ps 对我有很大帮助。

【问题讨论】:

  • 这不是一个 dup,因为它专门询问 C,而所谓的 'dup' 专门询问 C++。
  • @sje 这个问题也说 C++...
  • @DannyBeckett 是的,我注意到了。我认为这与我的观点无关,因为这个(与另一个不同)询问 C,这使得它在性质上有所不同。

标签: c++ c


【解决方案1】:

在 C++ 中,您可以使用全局函数 std::getline,它接受一个字符串和一个流以及一个可选的分隔符并读取 1 行,直到达到指定的分隔符。一个例子:

#include <string>
#include <iostream>
#include <fstream>

int main() {
    std::ifstream input("filename.txt");
    std::string line;

    while( std::getline( input, line ) ) {
        std::cout<<line<<'\n';
    }

    return 0;
}

此程序从文件中读取每一行并将其回显到控制台。

对于C,你可能正在考虑使用fgets,我已经有一段时间没有使用C了,这意味着我有点生疏,但我相信你可以使用它来模拟上述C++程序的功能像这样:

#include <stdio.h>

int main() {
    char line[1024];
    FILE *fp = fopen("filename.txt","r");

    //Checks if file is empty
    if( fp == NULL ) {                       
        return 1;
    }

    while( fgets(line,1024,fp) ) {
        printf("%s\n",line);
    }

    return 0;
}

限制是该行不能超过您正在读取的缓冲区的最大长度。

【讨论】:

  • 谢谢。我们如何在 C 中做同样的事情?有吗?
  • 更新了我的帖子,说明我是如何回忆的,我希望它是正确的,否则一旦有人指出我做错了什么,我会更正帖子。
  • 谢谢,我想知道是否有比使用固定长度的缓冲区更好的方法。我想我现在知道我们需要对缓冲区大小进行硬编码。
  • 我猜您可以存储“行”的起始位置(文件开头或新行之后),然后扫描文件直到到达行尾或行尾文件。然后取这个位置,找出与第一个位置的字节差,分配一个大缓冲区来保存这个字节数,使用 fseek 将 fp 设置为行首并将数据读入缓冲区?我希望这是有道理的。
  • 请关闭文件指针fclose (fp);
【解决方案2】:

在 c 中,您可以使用 fopen 和 getch。通常,如果您不能完全确定最长行的长度,您可以分配一个大缓冲区(例如 8kb)并且几乎可以保证获取所有行。

如果有可能你的行真的很长并且你必须逐行处理,你可以 malloc 一个合理的缓冲区,并在每次接近填充时使用 realloc 将其大小加倍。

#include <stdio.h>
#include <stdlib.h>

void handle_line(char *line) {
  printf("%s", line);
}

int main(int argc, char *argv[]) {
    int size = 1024, pos;
    int c;
    char *buffer = (char *)malloc(size);

    FILE *f = fopen("myfile.txt", "r");
    if(f) {
      do { // read all lines in file
        pos = 0;
        do{ // read one line
          c = fgetc(f);
          if(c != EOF) buffer[pos++] = (char)c;
          if(pos >= size - 1) { // increase buffer length - leave room for 0
            size *=2;
            buffer = (char*)realloc(buffer, size);
          }
        }while(c != EOF && c != '\n');
        buffer[pos] = 0;
        // line is now in buffer
        handle_line(buffer);
      } while(c != EOF); 
      fclose(f);           
    }
    free(buffer);
    return 0;
}

【讨论】:

  • 字符 c; ???!!!关闭(f) ??和malloc.h!!!不是 stdlib.h
【解决方案3】:

在 C 中,fgets(),您需要知道最大大小以防止截断。

【讨论】:

  • 这是 C 的最佳答案,它应该有更多的支持。 (其实getline更好看,但是不规范)
【解决方案4】:

我不太擅长 C,但我相信这段代码应该让你完成单行直到最后......

 #include<stdio.h>

 int main()   
{      
  char line[1024];    
  FILE *f=fopen("filename.txt","r");    
  fscanf(*f,"%[^\n]",line);    
  printf("%s",line);    
 }    

【讨论】:

  • 您应该避免使用fscanf,因为它会导致缓冲区溢出。它现在提供了将输入大小限制为正在写入的缓冲区大小的方法(此处为line)。
【解决方案5】:

getline() 是您正在寻找的。在 C++ 中使用字符串,无需提前知道大小。

假设 std 命名空间:

 ifstream file1("myfile.txt");
 string stuff;

 while (getline(file1, stuff, '\n')) {
      cout << stuff << endl;
 }

 file1.close();

【讨论】:

  • 注意:你想要std::getline(std::istream&amp;, std::string&amp;) 而不是std::istream::getline
  • 我们如何在 C 中做到这一点?
  • @EternalLearner,我在此处发布了一些示例代码(和截屏视频):spectrum42.com/introduction-to-c-reading-a-line-of-text
猜你喜欢
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
相关资源
最近更新 更多