2013-12-04 3 views
0

Я хочу ввести строковый массив в C++. Например:Как ввести строковый массив в C++

name[]={"jun","hua","kyu",..} 
       cout<<name[2]; 

выхода: ху

Это мой код, но строка, что я вход не останавливаюсь. Я не знаю, как это исправить. Пожалуйста, помогите мне. Спасибо.

string name[50]; 
string st; 
int i=0; 
    do{ 
      cin>>st; 
      name[i]=st; 
      i++;  
     } while (st!="\0"); 
+0

Использовать ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector) –

+0

' строка, которую я вводил, не останавливается' Что значит? –

+2

Кроме того, я бы ожидал, что ваш пример кода будет выводиться 'kyu', а не' hua' –

ответ

1

отформатированный вход, cin>>st будет пропускать все пробелы (включая пустые строки), и дать вам первое слово, которое он находит.

Я предполагаю, что вы хотите остановиться, когда есть пустая строка. Вы могли бы сделать что-то подобное, чтобы читать целые строки:

while (i < 50 && getline(cin, st) && !st.empty()) { 
    name[i] = st; 
    i++; 
} 

Если вы хотите прочитать отдельные слова, и позвольте несколько слов на строке, а затем разобрать каждую строку после прочтения:

while (i < 50 && getline(cin, st) && !st.empty()) { 
    std::stringstream ss(st); 
    std::string word; 
    while (i < 50 && ss >> word) { 
     name[i] = word; 
     ++i; 
    } 
} 

Вы должны использовать std::vector<string> name;, а не массив фиксированного размера, и добавлять имена с push_back(), чтобы избежать уродливых проверок диапазона в моем коде или возможности ужасных ошибок повреждения стека в вашем.

+0

Хотя ваш код не страдает от этой проблемы, вы не упоминаете, почему его код не работает: тот факт, что, как только он достигнет конца файла, 'std :: cin >> st' не удастся, возможно, без изменения 'st', поэтому он будет циклически навсегда. –

+0

@JamesKanze: Действительно, я предполагал, что код OP пытался искать пустую строку, а не конец (перенаправленного) файла, и не мог быть обеспокоен, чтобы написать полное эссе о том, как использовать I/O. –

+0

Чтобы быть откровенным, я не слишком уверен, что пытается сделать OP. Ясно, что он никогда не проверяет, достиг ли вход, и имеет бесконечный цикл (если только ему не удалось получить символ '' \ 0'' на входе). –

1

Вы должны положить std::cin в состояние цикла while, таким образом, когда он терпит неудачу (что будет, когда вы достигнете нулевой завершающей строки), он вернет false, и он покинет цикл.

Вот пример использования std::vector

#include <string> 
#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<std::string> userInputVec; 
    std::string input; 
    while(std::cin >> input) 
    { 
     userInputVec.push_back(input); 
    } 
} 
+0

Не «внутри цикла while», а в состоянии цикла while (как и в вашем примере). –

+0

@JamesKanze Rockie ошибка. Исправлена. – Caesar

0

вы отправляете ли нулевой символ во входном потоке вашей программы? Я предполагаю, что вы этого не сделаете, так что лучший способ написать цикл будет:

while (std::cin >> st) { 
    name[i] = st; 
    ++i; 
} 

std::istream::operator>>() возвращает поток чтения. Если он не смог прочитать запрошенный тип, в потоке будет включен бит сбоя, и результат будет равен false при выдаче в виде булева.

Кроме того, вы должны проверить значение i, чтобы не писать за пределами name.

1

Используйте вектор строк:

std::vector<std::string> strings; 

прочитанной строки в strings:

for(std::string s; std::cin >> s;) 
    strings.push_back(std::move(s)); 

печати из строк:

for(auto& s : strings) 
    std::cout << s << '\n'; 
+0

FWIW: если 'std :: cin >> s' преуспевает,' '' никогда не будет пустым. –

0

я надеюсь, что это поможет UU

string name[50]; 
string st; 
int i=0; 
    do{ 
      cin>>st; 
      name[i]=st; 
      i++;  
     } while (st!="\n"); 

или использовать

string name[50]; 
string st; 
int i=0; 
    do{ 

      getline(cin,name[i]); 
      i++;  
     } while (i<50); 
+1

Ни один из них не будет работать. В первом случае 'std :: cin >> st' будет _never_ помещать' '\ n'' в' st'. По определению. Во втором, в какой-то момент, вы достигнете конца файла, 'std :: getline' потерпит неудачу и может или не может изменить' name'. –

1

Это не для меня ясно, что вы пытаетесь сделать.Если содержимое файла составляет "kyu", тогда вход определенно остановится, когда он достигнет конца файла. То, что я подозреваю (но я действительно просто догадываюсь) заключается в том, что вы выводите строки без разделителя, и поэтому вход не знает, где заканчивается каждая строка , и читает все символы как одну строку , В другими словами, ваш выходной файл содержит "junhuakyu...".

При выводе строк (и многих других вещей) в качестве текста вы должны найти какой-либо способ их разграничения . Если строки используют ограниченный набор символов (например, просто буквы), часто достаточно, чтобы просто вставить символ разделителя между каждой строкой , выбирая строку, которая не может отображаться в строках. Для Например:

for (auto p = std::begin(name); p != std::end(name); ++ p) { 
    if (p != std::begin(name)) { 
     std::cout << ' '; 
    } 
    std::cout << *p; 
} 

Это даст вам что-то вроде "jun hua kyu ..." в файле , который можно легко прочитать с помощью:

std::string st; 
while (std::cin >> st) { 
    // ... 
} 

Который воспитывает secont проблемы с вашим кодом. Вы используете результаты того, что вы прочитали, без проверки, удалось ли прочитать . Если он не работает (например, из-за конца файла), то st не может быть изменен; во всяком случае, если файл является файлом , и на самом деле содержит только текст, вы никогда не получите st == "\0"; это может произойти только в том случае, если файл фактически содержит символ a '\0' (что не является законным, если это текстовый файл).

Наконец, конечно: выбор разделителя зависит от вас. Белое пространство особенно прост; если строки могут содержать пробелы, вы можете выбрать '\n' и использовать std::getline для чтения. И если хуже ухудшается, а строки могут быть буквально любыми, вам придется реализовать какой-то механизм кавычек, возможно с escape-символами.

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