2013-10-24 4 views
-2

Это похоже на такую ​​легкую задачу, но все, что я пробовал, пока не работает.Прочитайте файл и создайте целочисленный массив динамически

У меня есть файл foo.txt:

3 
3 4 2 

Теперь я хочу, чтобы прочитать этот файл, прочитать первую строку и экземпляр целочисленный массив с размером числа он прочитал на первой линии. Затем он должен заполнить этот массив элементами во второй строке, которые имеют одинаковое количество элементов и отмечены в строке 1.

+1

Не могли бы вы поделиться некоторыми из ваших решений, которые не сработали? – Jimbo

+3

_Это похоже на такую ​​легкую задачу, но вы никогда не искали это на SO, несколько вопросов, связанных с этим – P0W

+0

@ P0W Я действительно сделал. Я пробовал последние 3 часа. Вот что я читал: http://stackoverflow.com/questions/890164/how-can-i-split-a-string-by-a-delimiter-into-an-array, http://stackoverflow.com/questions/11546177/how-to-read-lines-of-text-from-file-and-put-them-in-a-array, http://stackoverflow.com/questions/7868936/c-read-file -лайн-by-line и несколько других. Основная причина в том, что я не привык к C/C++ и странной обработке файлов ('fstream',' iostream') – cherrun

ответ

2

Если мы собираемся дать вам пример кода, мог бы также показать вам лучший способ сделать это:

std::ifstream datafile("foo.txt"); 

if (!datafile) { 
    std::cerr << "Could not open \'foo.txt\', make sure it is in the correct directory." << std::endl; 
    exit(-1); 
} 

int num_entries; 
// this tests whether the number was gotten successfully 
if (!(datafile >> num_entries)) { 
    std::cerr << "The first item in the file must be the number of entries." << std::endl; 
    exit(-1); 
} 

// here we range check the input... never trust that information from the user is reasonable! 
if (num_entries < 0) { 
    std::cerr << "Number of entries cannot be negative." << std::endl; 
    exit(-2); 
} 

// here we allocate an array of the requested size. 
// vector will take care of freeing the memory when we're done with it (the vector goes out of scope) 
std::vector<int> ints(num_entries); 
for(int i = 0; i < num_entries; ++i) 
    // again, we'll check if there was any problem reading the numbers 
    if (!(datafile >> ints[i])) { 
     std::cerr << "Error reading entry #" << i << std::endl; 
     exit(-3); 
    } 
} 

Demo (с небольшими изменениями, потому что я не могу предоставить файл с правом имя на ideone): http://ideone.com/0vzPPN

+0

Хорошо. Теперь я уверен, что с моей настройкой что-то не так.Я получаю такие ошибки, как 'No member named 'cerr' в пространстве имен 'std'',' No member named' vector 'в пространстве имен' std '; вы имели в виду «гекто»? ». – cherrun

+0

@cherrun: Убедитесь, что у вас '#include ' и '#include ' и '#include '. –

+0

Да, я пропустил это. Теперь мой 'datafile' равен' nil/null'. Это просто дает мне ошибку «Could not open ...», хотя файлы находятся в одной папке. И да, я изменил имя файла. – cherrun

0

Вы должны использовать объект ifstream так же, как вы используете CIN

ifstream fin("foo.txt"); //open the file 
if(!fin.fail()){ 
    int count; 
    fin>>count; //read the count 
    int *Arr = new int[count]; 

    for(int i=0;i<count;i++){ //read numbers 
     fin>>Arr[i]; 
    } 
    //... do what you need ... 

    //... and finally ... 
    delete [] Arr; 
} 
+1

Утечка памяти, некорректная обработка ошибок, ... –

+0

Это всего лишь образец, но я редактирую утечку памяти ... – SHR

+0

Почему вы беспокоитесь об управлении памятью здесь? Это совершенно не нужно. 'fin >> count; std :: vector vec (count); ... fin >> vec [i]; ... ' –

0

Если открыть файл с помощью input filestream вы можете просто сделать:

std::ifstream file_txt("file.txt"); 

int number_count = 0; 
file_txt >> number_count; // read '3' from first line 

for (int number, i = 0; i < number_count; ++i) { 
     file_txt >> number; // read other numbers 
     // process number 
} 

потокового видео так же, как другие стандартные потоки (std::cin , std::cout) может применяться форматирование в зависимости от типа, поставляемого в operator>> (в данном случае int). Это относится как к вводу, так и к выходу.

+0

неправильная обработка ошибок ... –

0

в качестве альтернативы, вы могли бы избежать всего нужно читать в размере заранее, просто загружая его в std::vector:

std::ifstream fin("myfile.txt"); 
std::vector<int> vec{std::istream_iterator<int>(fin), std::istream_iterator<int>()}; 
fin.close(); 

или, если вы не можете использовать синтаксис C++ 11:

std::ifstream fin("myfile.txt"); 
std::vector<int> vec; 
std::copy(std::istream_iterator<int>(fin), std::istream_iterator<int>(), std::back_inserter(vec)); 
fin.close(); 
+0

Подождите, как это решение на основе списка инициализации будет работать без 'back_inserter'? –

+0

@ polkovnikov.ph Это не нужно. У него есть исходный и конечный итератор для копирования. –

Смежные вопросы