Строковое чтение в C и C ++? - PullRequest
5 голосов
/ 08 апреля 2011

Я хочу читать построчно из файла на C или C ++, и я знаю, как это сделать, когда я предполагаю некоторый фиксированный размер строки, но есть простой способ как-то вычислить или получить точный необходимый размер для строки или всех строк в файле? (Чтение слово за словом до новой строки также хорошо для меня, если кто-то может сделать это таким образом.)

Ответы [ 7 ]

7 голосов
/ 08 апреля 2011

Если вы используете потоковый ридер, все это будет скрыто от вас. Смотри 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";
}
4 голосов
/ 08 апреля 2011

В C, если у вас есть библиотеки POSIX 2008 (например, более поздние версии Linux), вы можете использовать функцию POSIX getline().Если у вас нет функции в ваших библиотеках, вы можете реализовать ее достаточно легко, что, вероятно, лучше, чем придумывать собственный интерфейс для выполнения работы.

В C ++ вы можете использовать std::getline().

Несмотря на то, что две функции имеют одно и то же базовое имя, соглашения о вызовах и семантика совершенно разные (поскольку языки C и C ++ совершенно разные) - за исключением того, что они обе читают строку данных из файлового потока,конечно.

Нет простого способа определить, насколько длинна самая длинная строка в файле, - кроме чтения всего файла, чтобы выяснить, что отчасти расточительно.

3 голосов
/ 08 апреля 2011

Я бы использовал 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;
}
1 голос
/ 08 апреля 2011

Вы не можете получить длину строки, пока не прочитаете ее. Однако вы можете многократно читать в буфер, пока не достигнете конца строки.

Для программирования на 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: %d\n", lineLength);
   return 0;
}
0 голосов
/ 09 апреля 2011

Вот способ чтения строк на языке C ++ с использованием алгоритмов std и итераторов:

#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));
}
0 голосов
/ 09 апреля 2011

getline это только POSIX, вот ANSI ( NO требуется информация о максимальном размере строки!):

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-текстовых файлов, работает на Unix для Unix и Windows-текстовых файлов

0 голосов
/ 08 апреля 2011

В 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);
...