fscanf无法正常使用字符串

时间:2021-11-20 13:18:56

I have a simple problem with my application. fscanf collects an entire word, but the size (length) is equal to the default size of currentName. If the currentName's default length value is lower then the length of a word, the word is cut.

我的应用程序有一个简单的问题。 fscanf收集整个单词,但大小(长度)等于currentName的默认大小。如果currentName的默认长度值低于单词的长度,则单词将被剪切。

For example:

if currentName="123" then fscanf will return "Art" instead of "Arthur".

如果currentName =“123”,则fscanf将返回“Art”而不是“Arthur”。

or

if currentName="123456789" then fscanf will return "Arthur 89" instead of "Arthur".

如果currentName =“123456789”,则fscanf将返回“Arthur 89”而不是“Arthur”。

File "list.txt" contains rows:

文件“list.txt”包含行:

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

What should I change to solve this issue? I have to use fscanf instead of fstream.

我应该改变什么才能解决这个问题?我必须使用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");
}

2 个解决方案

#1


scanf scans %s into a char array, not a std::string.

scanf将%s扫描到char数组中,而不是std :: string。

std::string is implemented with something like struct { size_t length; char* buffer; }, so writing into buffer will actually change the string. However, since it tracks its length explicitly, the '\0' at the end of the string won't be considered a terminator like it would in a character-array string.

std :: string是用struct {size_t length; char * buffer;因此写入缓冲区实际上会改变字符串。但是,由于它显式地跟踪其长度,因此字符串末尾的'\ 0'将不会像字符数组字符串中那样被视为终结符。

You could just scan into a char array, but the C++ish way to do this would be to use std::ifstream.

你可以直接扫描到一个char数组,但C ++的方法是使用std :: ifstream。

#2


You cannot modify the internal buffer of an std::string directly as you try to do here. To read a string, use a stream:

您尝试在此处执行此操作时,无法直接修改std :: string的内部缓冲区。要读取字符串,请使用流:

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

If you really need to use fscanf, use a big enough std::vector<char> instead and use it like a C-style string.

如果你真的需要使用fscanf,请使用足够大的std :: vector ,并将其用作C风格的字符串。

#1


scanf scans %s into a char array, not a std::string.

scanf将%s扫描到char数组中,而不是std :: string。

std::string is implemented with something like struct { size_t length; char* buffer; }, so writing into buffer will actually change the string. However, since it tracks its length explicitly, the '\0' at the end of the string won't be considered a terminator like it would in a character-array string.

std :: string是用struct {size_t length; char * buffer;因此写入缓冲区实际上会改变字符串。但是,由于它显式地跟踪其长度,因此字符串末尾的'\ 0'将不会像字符数组字符串中那样被视为终结符。

You could just scan into a char array, but the C++ish way to do this would be to use std::ifstream.

你可以直接扫描到一个char数组,但C ++的方法是使用std :: ifstream。

#2


You cannot modify the internal buffer of an std::string directly as you try to do here. To read a string, use a stream:

您尝试在此处执行此操作时,无法直接修改std :: string的内部缓冲区。要读取字符串,请使用流:

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

If you really need to use fscanf, use a big enough std::vector<char> instead and use it like a C-style string.

如果你真的需要使用fscanf,请使用足够大的std :: vector ,并将其用作C风格的字符串。