2013-05-21 2 views
0

У меня есть структура с int и двумя строками. При чтении в файле он разделяется запятой на первые два значения, а последнее значение заканчивается новой строкой. Однако третий аргумент может быть пустым.разделенный запятой поток в структуру

данные ex: 7, john doe, 123-456-7891 123 fake st.

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

Первый вопрос я должен использовать класс вместо? Я видел getline(stream, myString, ',');, но мои аргументы - разные типы данных, поэтому я не могу просто выбросить их все в вектор.

мой код:

struct Person{ 
    int id;//dont care if this is unique 
    string name; 
    string extraInfo; 
}; 

int main(int argc, char* argv[]){ 
    assert(argc ==2 && "Invalid number of command line arguments"); 
    ifstream inputFile (argv[1]); 
    assert(inputFile.is_open() && "Unable to open file"); 
} 

Каков наилучший способ хранения этой информации и извлечения ее из файла, разделенных запятыми для первых двух и заканчивается с новой строки? Я также хочу, чтобы программа игнорировала пустые строки в файле.

+0

ли данные в формате CSV, или просто свое собственное кодирование, где двойные кавычки вокруг строковых значений гарантированы? (В CSV они не понадобятся в некоторых случаях, например, если кто-то использует только одно имя, например, Мадонна). –

+0

цитат никогда не бывает, дурная привычка, я думаю. Удалили их. – Lainezor

ответ

1

Я читал файл по строкам, используя обычный getline(). Затем поместите его в stringstream для дальнейшего анализа или используйте функции string's find(), чтобы разделить текст вручную.

еще несколько заметок:

  • Я не понимаю, ваш первый вопрос об использовании класса. Если вы имеете в виду для Person, тогда ответ заключается в том, что это не имеет значения.
  • Использование assert для чего-то, у вас нет контроля, неверно, например argc. Это следует использовать только для проверки того, что вы не сделали ошибку программирования. Кроме того, если вы #define NDEBUG, утверждения все исчезли, поэтому они не должны быть частью вашей логики программы. Вместо этого запустите std :: runtime_error («не удалось открыть файл»).
  • Возможно, вам не нужны двойные кавычки в ваших строках. Кроме того, вы можете захотеть, чтобы "a,b" не делился запятой. Убедитесь, что у вас есть тесты, которые утверждают требуемую функциональность.
+0

1- Я думал, что класс может иметь некоторую разницу.2 - моя программа всегда должна иметь 2 аргумента командной строки во все времена. 3- Я не хотел вставлять цитаты, я их вынул. – Lainezor

+0

Я понимаю, что он должен иметь два параметра, но это не то, что вы контролируете программным кодом, вы можете только убедиться, что он вызван правильно. 'assert()' предназначен для улавливания ошибок программирования, поэтому он не подходит для проверок времени выполнения.Ваше использование не является неправильным, это просто против конвенции и отправки неправильного неявного сообщения. –

0

Вы все еще можете использовать getline подход к tokenising линии, но вы должны сначала прочитать строку:

vector<Person> people; 
string line; 
int lineNum = 0; 

while(getline(inputFile, line)) 
{ 
    istringstream iss(line); 
    lineNum++; 

    // Try to extract person data from the line. If successful, ok will be true. 
    Person p; 
    bool ok = false; 

    do { 
     string val; 
     if(!getline(iss, val, ',')) break; 
     p.id = strtol(val.c_str(), NULL, 10); 

     if(!getline(iss, p.name, ',')) break; 
     if(!getline(iss, p.extraInfo, ',')) break; 

     // Now you can trim the name and extraInfo strings to remove spaces and quotes 
     //[todo] 

     ok = true; 
    } while(false); 

    // If all is well, add the person to our people-vector. 
    if(ok) { 
     people.push_back(p); 
    } else { 
     cout << "Failed to parse line " << lineNum << ": " << line << endl; 
    } 
} 
+0

Какова цель lineNum? – Lainezor

+0

Номер строки. Dunno о вас, у меня просто есть эта привычка подсчета строк, так что, когда я получаю сообщение об ошибке, я могу вывести, на какой строке это произошло. Вы увидите, что я использую его внизу в случае ошибки. Имейте в виду, что этот код не обрабатывает кавычки и т. Д. Для этого вам будет лучше выполнять быструю функцию, которая вытаскивает одну строку с кавычками или не кавычками из потока (чтобы вы не нарушали неправильную запятую). – paddy

0

После того, как вы получите строку в строку, используя GetLine, использование strtok.

char myline[] = "7, john doe, 123-456-7891 123 fake st."; 
char tokens = strtok(myline, ","); 
while(tokens) 
{ 
    //store tokens in your struct values here 
} 

Вам необходимо включить #include <string.h> использовать strtok

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