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

295
15 декабря 2016, 16:08

Как написать код так, чтобы мой массив заполнялся текстом в 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");
Answer 1
// не компилировал, но бьюсь об заклад - работает.
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 вариант - hashcode.ru/questions/200121/

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;
}

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

Answer 2

Пожалуй самый быстрый способ чтения текстового файла (система удаляет \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);
}
Answer 3

Не отлаживал ваш код, но могу предположить, что вы свой массив располагаете на стеке, который переполняется и рушит вашу программу. Сделайте динамическое выделение памяти в куче, пользуясь синтаксисом new/

Необходимо отметить еще и тот факт, что если вы читаете данные из файла, то не можете заранее знать размер необходимого вам массива, поэтому массива размером 100*100 скорее всего будет либо недостаточным, либо наоборот излишним - угадать вы вряд ли сможете. Динамическое выделение памяти может помочь и здесь

Answer 4

Выделять память можно динамически, например, по мере чтения текста расширять realloc'ом, или изначально выделить 500 килобайт, что означает массив, размерность которого равна 500 000.

READ ALSO
R6010 abort() has been called

R6010 abort() has been called

http://pastebincom/g5dJAAYM# Выходит вот такая ошибка в данном коде

257
Как получить цвет пикселя виджета  QT?

Как получить цвет пикселя виджета QT?

Нужно получить значание RGB именно одной точки на QWidget

284
Определение типа файла

Определение типа файла

Здравствуйте, форумчане!

224
Перевести число в строку

Перевести число в строку

Нужно написать собственную функцию перевода из числа в строкуВот вроде бы обратная вещь

201