C++ 从输入文件中读取复合键和数值的正确方法是什么?

C++ 从输入文件中读取复合键和数值的正确方法是什么?,c++,input,C++,Input,我正在尝试读取一个文本文件,该文件由多个字符串组成,这些字符串表示一个键/值(键是一个字母/“”/3digits/“”/2letters格式的车号;值是无符号的long;\t或它们之间的“”)或一个空行,例如: 空行 空行 Z999 ZZ80 A 000 AA 124 Z 666 ZZ 42 为此,我使用了一个cin.getline()函数,读取整行并遍历每个字符,将一个键和一个值保存到一个“element”变量中,然后将其推送到一个向量中。但出于某种原因,该程序似乎出人意料地工作,给出了一个奇

我正在尝试读取一个文本文件,该文件由多个字符串组成,这些字符串表示一个键/值(键是一个字母/“”/3digits/“”/2letters格式的车号;值是无符号的long;\t或它们之间的“”)或一个空行,例如:

空行
空行
Z999 ZZ80
A 000 AA 124
Z 666 ZZ 42

为此,我使用了一个cin.getline()函数,读取整行并遍历每个字符,将一个键和一个值保存到一个“element”变量中,然后将其推送到一个向量中。但出于某种原因,该程序似乎出人意料地工作,给出了一个奇怪的输出:

0
0
Z999 ZZP80
A 000 AA | 124
Z666ZZ*42

到目前为止,我一直在试图分析可能出现的问题,但我就是看不到。我也尝试过使用其他工具,如scanf()或cin.get(),但失败惨重。有人能给我解释一下为什么会发生这种情况,也许能给我一个更正确的方法来解决这个问题吗?代码如下:

struct kv {
    char key[8];
    unsigned long long val;
};

int main()
{
    std::vector<kv> data_vector;
    kv element;

    char str[64] = {};
    char num[32] = {};
    while (std::cin.getline(str, 64)) {
        if (str[0] == ' ' || str[0] == '\n' || str[0] == '\t' || str[0] == EOF) {
            continue;
        }
        size_t i = 0, n = 0;
        for (i = 0; i < 8; i++)
            element.key[i] = str[i];
        while (!(str[i] >= '0' && str[i] <= '9'))
            i++;
        while (str[i] >= '0' && str[i] <= '9')
            num[n++] = str[i++];
        element.val = atoi(num);
        data_vector.push_back(element);
        for (n = 0; n < 32; n++)
            num[n] = 0;
        for (i = 0; i < 64; i++)
            str[i] = 0;
    }
    for (size_t i = 0; i < data_vector.size(); i++) {
        std::cout << data_vector[i].key << "\t" << data_vector[i].val << std::endl;
    }
    return 0;
}
struct kv{
字符键[8];
无符号长val;
};
int main()
{
std::矢量数据\矢量;
千伏元件;
char str[64]={};
char num[32]={};
while(std::cin.getline(str,64)){
如果(str[0]=''| | str[0]='\n'| | str[0]='\t'| | str[0]==EOF){
继续;
}
尺寸i=0,n=0;
对于(i=0;i<8;i++)
element.key[i]=str[i];

虽然(!(str[i]>='0'&&str[i]='0'&&str[i]我想你可能不理解
std::cin.getline()
是如何工作的。首先,你不想测试
std::cin.getline()
的返回值是真是假。你需要检查
eof
还是
fail
。其次,
std::cin.getline()
丢弃换行符,因此无需检查“\n”。循环可以这样开始:

for ( ; ; )
{
    str[0] = '\0'; // Clear any previous data
    std::cin.getline(str, 64);
    if ( std::cin.eof() )
    {
        break; // No more data, exit loop
    }
    if ( std::cin.fail() || (str[0] < 'A') )
    {
        continue; // Empty line or line does not start with a letter
    }
    . . .
(;;)的

{
str[0]='\0';//清除以前的任何数据
标准:cin.getline(str,64);
if(std::cin.eof())
{
break;//不再有数据,退出循环
}
if(std::cin.fail()| |(str[0]<'A'))
{
continue;//空行或行不以字母开头
}
. . .

str[0]==EOF
您无法将
char
与EOF进行比较您不需要这些循环来将最后的字符设置为0。只需执行
num[n]=str[i]=0;
更改
char键[8];
char键[9];
并添加
element.key[8]='\0'
@JimRhodes这有帮助,但对于空行它仍然是错误的:(