2015-05-04 4 views
0

У меня есть простая проблема с моим приложением. fscanf собирает целое слово, но размер (длина) равен размеру по умолчанию currentName. Если значение длины currentName по умолчанию меньше, чем длина слова, слово разрезается.fscanf работает неправильно со строкой

Например:

если currentName = "123" тогда fscanf вернется "Искусство" вместо "Артур".

или

если currentName = "123456789", то fscanf вернется "Артур 89" вместо "Артур".

Файл "list.txt" содержит строки:

Arthur 30 1550 
Ben 32 2100 
Charlie 25 1850 
Danny 46 2400 
Edward 35 2750 

Что я должен изменить, чтобы решить эту проблему? Мне нужно использовать fscanf вместо fstream.

#include <iostream> 
#include <stdio.h> 
#include <string> 
#include <stdlib.h> 
using namespace std; 
class Worker 
{ 
private: 
    string name; 
    int age; 
    double salary; 
public: 
    Worker() 
    :name(""),age(99),salary(0) 
    {} 
    Worker(string name, int age, double salary) 
     :name(name),age(age),salary(salary) 
    {} 
    void showVaulues() 
    { 
     cout<<endl; 
     cout<<"Name:\t"<<name<<endl; 
     cout<<"Age:\t"<<age<<endl; 
     cout<<"Salary:\t"<<salary<<endl; 
    } 
}; 
int main() 
{ 
    FILE *myfile=NULL; 
    string currentName="123456789"; 
    int currentAge=0; 
    double currentSalary=999999; 
    Worker *ptr=NULL; 
    myfile=fopen("list.txt","r"); 
    while (feof(myfile) == 0) 
    { 
     fscanf(myfile,"%s %d %lf\n",&currentName[0],&currentAge,&currentSalary); 
     ptr=new Worker(currentName,currentAge,currentSalary); 
     ptr->showVaulues(); 
    } 
    system("pause"); 
} 
+4

Почему это помечено как 'C', когда оно явно' C++'? – PaulMcKenzie

+1

'fscanf (myfile,"% s% d% lf \ n ", & currentName, ...);' Какой компилятор вы используете? Если это что-то пред-C++ 11, это неопределенное поведение для заполнения строки 'std :: string'. И я даже не уверен, что он работает с C++ 11. – PaulMcKenzie

+0

@PaulMcKenzie Подождите, это законно в C++ 11? –

ответ

1

Вы не можете изменить внутренний буфер с std::string непосредственно, как вы пытаетесь сделать здесь. Чтобы прочитать string, использовать поток:

std::ifstream in ("list.txt"); 
int >> currentname >> currentAge >> currentSalary; 

Если вам действительно нужно использовать fscanf, использовать достаточно большой std::vector<char> вместо этого и использовать его как строку C-стиле.

1

scanf сканирует %s в массив char, а не std::string.

std::string реализован с чем-то вроде struct { size_t length; char* buffer; }, поэтому запись в buffer фактически изменит строку. Однако, поскольку он отслеживает свою длину явно, '\0' в конце строки не будет считаться терминатором, как это было бы в строке символьного массива.

Вы можете просто сканировать в массив char, но C++ может сделать это, используя std::ifstream.

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