Как записать текст в массив?

Рейтинг: 2Ответов: 2Опубликовано: 18.12.2014

Как написать код так, чтобы мой массив заполнялся текстом в 500 Кб и не захлебывался.

int main()  
{  
    char mass [100][100]; <--что тут изменить????   
    char slovo[80];  
    int i=0;  
    int a,k=0;   
    setlocale(LC_ALL, "Russian");  
FILE *f;  
f=fopen("text.txt", "r");  
if(f==NULL) printf("файл text.txt не открыт\n");

Ответы

▲ 3Принят
// не компилировал, но бьюсь об заклад - работает.
int main()  
{ char mass[100][100] = {0}; // тут можно ничего не менять - ТАМ надо изменить многое!  
  char slovo[80] = {0};  // = {0} - занулить массивы
  int i=0;  
  int rows_count=0;  // Нормальное имя!!!

  setlocale (LC_ALL, "Russian");

  FILE *f = fopen ("text.txt", "rt");  
  if( !f )
  { fprintf (stderr,"Файл text.txt не может быть открыт.\n");
    goto end;
  }
   // ошибки аккуратно выводим в стандартный поток ошибок

  // %99s - счититается только 99 символов, или меньше до перевода строки (\n)
  // последний символ - терминирующий ноль, поэтому не 100
  // считается не более 100 строк, тут можно сто.
  //  mass[i] - это массив, соответственно без &
  // eof - плохо, лучше то, что scanf успешно отработал - 
  // возвращает кол-во успешно считанных процентиков
  while( i < 100 && fscanf (f, "%99s", mass[i]) == 1 )  
   printf("%s\n", mass[i++]);
  rows_count = i;  

  // !! ФАЙЛ ЗАКРЫТЬ !!! Ну как так-то!?
  if (f) fclose (f);

  printf ("Введите слово для поиска: ");
  scanf ("%79s", slovo); // опять ограничение на длину...

  if( *slovo ) // * - нулевой элемент строки, сам указатель у тебя валидный
  { for(i=0; i<rows_count; ++i)  
    if( !strcmp (slovo, mass[i]) )  
    { printf ("\n index  %d  ",i); 
      goto end; // return - не по всем ветвлениям - делай так, чтобы этого избежать
    }   

    // if( strcmp (slovo, mass[k]) ) // !!! - это что вообще??
    printf ("слово не найдено");
  }

end:;
 // Очистка памяти, освобождение ресурсов.
 system ("pause");
 return 0; // успешный выход
}

Отвечаю: Как прочитать файл до конца:

{
 int i=0;
 long long  size=0;
 FILE *fin = NULL;

 // rt - окрыть как текст, rb - открыть, как бинарник
 fin = fopen (filename, "rt"); 
 if ( !fin )
  goto end;

 // встанем в самый конец файла
 fseek (fin, 0, SEEK_END); // это в функция из stdio для random access в файле
 size = ftell (fin); //  это в функция из stdio говорит, где мы находимся 
 fseek(fin, 0, SEEK_SET); // снова  встанем в начало

 // рассточние между концом и началом - размер файла в байтах
 // Пусть наш файл не в Юникода, а в ASCII

 // тогда выделяем память под строку
 char *the_big_string = (char*)malloc (sizeof (char) * size + 1);
 if ( !the_big_string )
  goto end;

 for (i=0; i<size; i++)
  // читаем посимвольно
  if ( fscanf (fin, "%c", &the_big_string[i]) != 1)
   goto end;
 the_big_string[i] = "\0"; // терминатор строки ставим вручную

 // файл считан - можно так, например.
 // ...
end:;
 if (the_big_string)
 { free (the_big_string); the_big_string = NULL; }
 if (fin)
 { fclose (fin); fin = NULL; }
 return 0;
}
//---------------------------------------------------------

II вариант - Как правильно написать realloc() для массива структур?

int i=0;
long long size = BIG_NUMBER;
char *the_big_string = (char*)malloc (sizeof (char) * size + 1);
if ( !the_big_string )
 goto end;

while( fscanf (fin, "%c", &the_big_string[i++]) == 1 )
 if ( i >= BIG_NUMBER )
 { char *tmp = realloc (the_big_string, sizeof (the_big_string) * 2);
   if (!tmp)
   { if (the_big_string) 
     { free (the_big_string);
       the_big_string = NULL;
     }
     goto end;
   }
 }
// !!! файл считан !!!

//---------------------------------------------------------

вариант №3 - для прошаренных, для тех, кто знает С++

int main ()
{
 std::ifstream  ifs ("text.txt"); // can throw exception
 std::string  file_content, tmp;

 while ( std::getline (ifs, tmp) )
  file_content += tmp; // память сама выделится
 // или can throw exception

 // !!! файл считан !!!

 // всё само закроется и очистится
 return 0;
}

// Вариант посимвольного считывания для С++
http://www.cyberforum.ru/cpp-beginners/thread527374.html
#include <string>
#include <fstream>

int main ()
{
 std::ifstream ifs ("text.txt"); // can throw exception
 std::string str;

 while (ifs)
 { char ch;
   ifs.get (ch);
   if( ifs.eof () )
    break;
   str += ch;
 } // end while
 // !!! файл считан !!!

 return 0;
}

И, вообще, всё прекрасно гуглится.

▲ 1

Пожалуй самый быстрый способ чтения текстового файла (система удаляет \r из хранимых на диске \r\n) целиком в память.

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

int
main (int ac, char *av[])
{
  FILE *fp;
  const char *fname;
  if (!(fp = fopen(fname = (av[1] ? av[1]: "1.txt"), "r"))) { // "rb" бинарный файл (\r перед \n сохранятся)
    perror(fname);
    exit(2);
  }

  fseek(fp, 0, SEEK_END);
  long lr, size = ftell(fp);
  rewind(fp);

  char *txt = (char *)malloc(size + 1); //или только в C++ new char [size + 1]; 
  txt[lr = fread(txt, 1, size, fp)] = 0;

  printf("file %s %ld bytes (disk)  %ld bytes (in memomory) (%ld lines?)\n",
         fname, size, lr, size - lr);

}