2010-05-12 3 views
0

У меня есть программа, которую мне нужно прочитать в массиве строк из файла. Массив должен быть строками типа C (char * или char []).C++ string array from ifstream

Используя следующий код, я получаю плохую ошибку доступа:

for (i = 0; i < MAX_WORDS && !inputFile.eof(); i++) { 
    inputFile >> words[i]; 
} 

слова объявлен как:

char *words[MAX_WORDS]; 
+0

может захотеть проверить другие биты ошибки (сбой и т. Д.) – Tom

+0

Что такое inputFile? – Patrick

+0

inputFile - это поток, как указано в заголовке. –

ответ

2

iostreams не выделяет память автоматически для вас, вы должны заранее выделить , В настоящее время у вас есть только массив указателей, содержащих значения мусора.

Обратите внимание, что вы не контролируете длину ввода здесь. Временное сохранение в строке C++ и выделение C-строк подходящего размера было бы предпочтительным.

В качестве альтернативы можно ограничить длину ввода с помощью setw() манипулятора:

inputFile >> std::setw(allocatedWordLength-1) >> words[i]; 
+0

Мне не разрешено использовать строки C++ вообще в моей программе (согласно пожеланиям моего воинственного учителя). setw, похоже, не работает для меня. Я где-то читал, что он определен в iomanip, но я получаю ошибки, когда пытаюсь его использовать. –

+0

@ Давид: Вы '#include '? Вы могли бы добавить ошибки в качестве обновления к вопросу или открыть новый вопрос о проблемах iomanip. –

+0

@ Учитель - Почему бы и нет? (Не волнуйтесь, это риторический вопрос.) – jmucchiello

0

ли каждая строка в массиве строки в файле? Вы используете std :: ifstream? Если этого не сделать, используйте std :: getline. GetLine читает в станд :: строку, но c_str() дает вам, ну, c_str использовать непосредственно или скопировать в в массив

1

Ваших декларации

char *words[MAX_WORDS]; 

только выделяет массив указателей, а не памяти для буферов. Эти указатели не указывают на выделенную память, поэтому, когда вы пишете на эти адреса, вы получаете ошибку доступа.

Вам необходимо выделить массив буферов. Один из способов, чтобы объявить двумерный массив:

char words[MAX_WORDS][MAX_WORD_LENGTH]; 

предполагая MAX_WORD_LENGTH устанавливается на сколь угодно долго ваши слова, возможно, может быть плюс один для нулевого терминатора. Тогда ваш цикл должен работать.

1

JohnMcG дал отличный ответ на вашу ближайшую проблему, но есть и другие вещи, которые могут быть обеспокоены тем, что не будет вписываться в комментарий. Помните, что массив символов может содержать строку на один символ, меньшую ее длины, поэтому используйте длину MAX_WORD_LENGTH + 1. Я также предлагаю инициализировать эти строки для нулевой строки, так что в начале каждой строки перед циклом есть «\ 0».

Есть ли какой-либо надежный предел длины слов? Если нет, проблема будет более тесно связана с строками C-стиля (хотя и не с C++-строками). Вам придется выделять указатели (как есть) и перераспределять их по мере необходимости при чтении символа по символу. Скудно, и это один случай, когда я рекомендую использовать malloc()/free()/realloc(), а не управление памятью C++.

Я предполагаю, что вы уже знаете, что вы читаете слова, а не линии. Имя вашего массива предполагает, что это обычная ошибка среди учащихся.

Вы не объявили i в инструкции for, так что это переменная с внешней областью, что позволяет использовать ее значение позже. Если да, помните, что .eof() не означает, что программа закончилась, это означает, что программа попыталась прочитать конец файла.Если файл заканчивается символом пробела (например, «\ n»), он будет читать последнее слово, а затем увеличивать i и ничего не читать. Если это не так, он попытается прочитать за конец файла при чтении последнего слова и не будет увеличивать значение i.

Если вам нужен подсчет слов, то, что вам нужно настроит память, как упоминались выше, и вы должны проверить, является ли words[i] пуст или нет (strlen() является излишеством, проверьте первый символ для \0).