将“firstword secondword”从文本文件中拉入单个char数组中

时间:2014-09-15 21:01:50

标签: c++

我收到了分段错误:当我在播放器文件中读取时出现核心转储错误。 我想添加" firstname lastname"到玩家结构。我正在尝试访问" 0th"人们并增加他们的名字,因为我需要第一个和最后一个,我不能简单地鳍>> people [i] .name在一个简单的for循环中,就像我对卡值(未显示)" heart two 2"例如

// deck of cards
// below are initializations
#include <iostream>
#include <fstream>
#include <ctime>
#include <stdlib.h>
#include <string>

using namespace std;

//globals
const int maxCards = 52;

//Structs
struct card {
    char suit[8];
    char rank[6];
    int cvalue;
    char location;
};

struct player {
    char name[];
    int total;
    card hand[];
};

//program
int main()
{
    char tempfName[100];
    char templName[100];

    //create struct array(s)
    card deck[52];
    card shuffledDeck[52];
    player people[4];

    //set defalt values
    for(int i=0;i<4;i++)
    {
        strcopy(people[i].name,"first last");
    }

    //open player names file
    ifstream fin2;
    string fin2Name;

    //get file name from user
    cout << "Enter player file name...(Players.txt)" << endl;
    getline(cin,fin2Name);
    fin2.open(fin2Name.c_str());

    //check if Players.txt opens correctly
    if(!fin2.good())
    {
        cout << "Error with player file!" << endl;
        return 0;
    }
    else
    {
        int j =0;
        //fin2 >> people[j].name;  //prime file
        while(fin2.good())
        {
            //find the length
            int index =0, length=0;
            while(tempfName[length] != '\0')
            {
                length++;
            }
            //now add space after first name
            tempfName[length] = ' ';
            length++;
            while(templName[index] != '\0')
            {
                tempfName[length] = templName[index];
                length++;
                index++;
            }
            tempfName[length]='\0';
            int counter =0;
            while(templName[counter] != '\0')
            {
                people[0].name[counter] = templName[counter]; //testing program on "0th" people
                counter++;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

在您的结构中,name[]hand[]的大小不确定。因此很难将任何内容读入其中。

然后,一旦打开了流,就会尝试确定单元化tempfName[]的长度。这不是没有好处:你不确定它是否终止并且你会超出界限!这是您的段错误的起源。

通过将它们声明为:

来考虑初始化这些
char tempfName[100]{};
char templName[100]{};

修复后,你的代码仍会在while (fin2.good())上永远循环而不读取任何内容,并勇敢地向tempfName添加一个空格,直到你出界。

现在假设您已解决所有这些问题,请为name设置一个长度,并取消注释您的信息流fin2 >> people[j].name;您还有一个非常危险的情况:如果数据的长度超过了你已经预见到,它会被截断,名称也没有终止'\ 0'。

建议1:

每当考虑存储字符串时,请考虑使用std :: string而不是char []。示例:

struct player {
    string name = "first last" ;   // initialisation value: no strcpy() needed !! 
    int total;
    card hand[5];  // length ?
};

建议2:

使用您的流读取循环作为循环条件:

    while (fin2 >> people[j].name) { ///!!!
         ...
         j++;  // don't foget to increment your counter 
    }   

但是要小心,因为>>一次会读取一个字符串,字符串首先以空格结尾(所以只有firstname)。

如果你采纳建议1,那么写起来会很容易:

    while (fin2 >> tempfName >> templName) {  ///!!!
        people[j++].name = tempfName + " " + templName; 
     }    

它应该与你的循环执行几乎相同的事情,但是指令和风险要少得多。

建议3:

如果玩家数量固定,请定义最大常数并使用a而不是一段时间来读取数据:

 const int max_player = 4; 
 player people[max_player];
 ... 
 for (j=0; j<max_player && (fin2 >> people[j].name); j++)  // instead of the former while

如果你的4的限制是arbirary,考虑使用向量。但那是目前的另一个故事。

答案 1 :(得分:0)

您的struct player定义无效:

struct player {
    char name[];
    int total;
    card hand[];
};

C字符串字段namehand需要有一个长度,例如

struct player {
    char name[32];
    int total;
    card hand[32];
};

你的编译器应该给你一个错误(&#34;不完整的类型&#34;)。

另请注意,由于您正在编写C ++代码,因此最好使用std::string而不是C风格的char *字符串 - 它会更容易,更强大,并且您赢得了#c;混合C和C ++习语。