Я получаю ошибку сегментации: ядро сбрасывает ошибку, когда я читаю в файле игроков. Я пытаюсь добавить оба "firstname lastname" в структуру игрока. Я пытаюсь получить доступ к "0-м" людям и увеличивать их имя, потому что мне нужны как первые, так и последние, я не могу просто fin >> people [i].name в просто для цикла, как я делаю для значения карты (не показано) "сердце два 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++;
}
}
}
}
В вашей структуре name[]
и hand[]
имеют неопределенный размер. Поэтому трудно читать что-либо в них.
Затем, как только вы открыли поток, вы пытаетесь определить длину униалиализованного tempfName[]
. Это нехорошо: вы не уверены, что он завершен, и вы выйдете за пределы! Это источник вашего segfault.
Подумайте об их активации, объявив их:
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
}
Однако будьте осторожны, потому что >>
будет читать по одной строке за раз, строка заканчивается на первом whilespace (так что только первое имя).
Если вы примете рекомендацию 1, было бы легко написать:
while (fin2 >> tempfName >> templName) { ///!!!
people[j++].name = tempfName + " " + templName;
}
который должен выполнять почти то же самое, что и ваш цикл, но с гораздо меньшими инструкциями и рисками.
Рекомендация 3:
Если количество игроков фиксировано, определите максимальную константу и вместо a используйте вместо 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, рассмотрите использование векторов. Но эта другая история на данный момент.
char tempfName[100] = "";
struct player
определение вашего конструктора:
struct player {
char name[];
int total;
card hand[];
};
C строковые поля name
и hand
должны иметь длину, например,
struct player {
char name[32];
int total;
card hand[32];
};
Ваш компилятор должен дать вам ошибку для этого ("неполный тип").
Следует также отметить, что, так как вы пишете C++ код, то лучше было бы использовать std::string
, а не C-стиль char *
строки - это будет проще, надежнее, и вы не будете смешивания C и [CN10 ] идиомы.