所以我遇到了这个问题,我现在已经试着解决了大约8个小时......我已经放弃了寻求答案而没有帮助。我已经尝试分别使用realloc()
和malloc()
,所以任何输入都会很棒!
这个在C中的目的是允许创建“地图”,我稍后将使用ncurses来创建地图。
文件的输入如下
10X16 de4 dw9 ds8 g8,7 m3,4 h6,5 p2,2
6X20 dn5 ds4 W4,3 e2,12 M1,1
10X13 ds3 dw9
10X12
5X4
6x12
以下是代码:
char *importLevel()
{
FILE *fPointer;
fPointer = fopen("Level", "r"); //Opens text file to read
char* rooms[150];// set up for memory allocation
char commands[150];// set up for pulling data from read file
while (!feof(fPointer))
{
fgets(commands,150, fPointer); // this takes each line from the file
}
*rooms = (char *) malloc(150 * sizeof(char)); // memory allocation
for (int i = 0; i < 150; i++)
{
if (rooms[i] != NULL)
{
*rooms[i] = commands[i]; // supposed to give rooms the string
}
}
fclose(fPointer);// close file
return *rooms; // return pointer
}
我希望我不像现在这样愚蠢!谢谢:))
编辑:我觉得我觉得很愚蠢
答案 0 :(得分:1)
这里有很多事情需要解决。
while (!feof(fPointer))
{
fgets(commands,150, fPointer); // this takes each line from the file
}
每次循环都会覆盖commands
中的数据。当循环退出时,您将读取并丢弃除最后一行之外的所有数据。您需要使用二维数组,或者更有可能在阅读时将数据存储到rooms
。第二种方式更快,使用更少的内存。
*rooms = (char *) malloc(150 * sizeof(char));
这种看起来像是在尝试创建一个二维数组。相反,你会想做这样的事情:
for (int ii = 0; ii < 150; ++ii)
rooms[ii] = malloc(150 * sizeof(char));
请注意,此malloc不会初始化内存。所以你的支票
if (rooms[i] != NULL)
会给你不明确的结果。 rooms[i]
的内容未定义。如果要将数组初始化为全零,请尝试使用memset
。
然后:
*rooms[i] = commands[i];
不会复制来自commands
的数据,而只会复制commands
中的第一个字符。要复制整个字符串,您需要使用strcpy
或strncpy
来避免潜在的缓冲区溢出问题。 memcpy
也可以复制一些字节而不是以空字符结尾的C字符串。
最后,返回*rooms
是一个等待发生的错误。作为参数传递rooms
并分配到其中,您会得到更好的服务。有关如何执行此操作,请参阅Allocate memory 2d array in function C。
答案 1 :(得分:0)
其他人指出了你需要做出的一些改变。所以,看看他们说了什么,并将你的版本与下面的版本进行比较。这应该有所帮助。
这是您程序的更正版本。根据您的代码和数据,我不得不猜测您的一些意图[请原谅无偿的样式清理]:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <malloc.h>
char **
importLevel()
{
FILE *fPointer;
char commands[150]; // file line buffer
int roomcnt = 0;
char *cp;
char *bp;
char **rooms = NULL; // set up for memory allocation
fPointer = fopen("Level", "r"); // Opens text file to read
if (fPointer == NULL) {
printf("importLevel: unable to open file -- %s\n",strerror(errno));
exit(1);
}
while (1) {
// this takes each line from the file
cp = fgets(commands, sizeof(commands), fPointer);
if (cp == NULL)
break;
// setup buffer for strtok
bp = commands;
// parse all words on line
while (1) {
// NOTE: the first assumes you want "g8,7" within a room
// the second assumes you want "g8,7" as two separate rooms
#if 1
cp = strtok(bp," \n");
#else
cp = strtok(bp," ,\n");
#endif
// strtok wants this on 2nd and subsequent loops for this line
bp = NULL;
// bug out if no more words on this line
if (cp == NULL)
break;
// increase room list size (allow space for terminator)
// NOTE: rooms will be preserved when we return from this function
rooms = realloc(rooms,sizeof(char *) * (roomcnt + 2));
// NOTE: cp is pointing to something in our stack frame that
// will go away when we return or when we read the next line
// so we must preserve it in the heap now
cp = strdup(cp);
// add the contents of the room
rooms[roomcnt] = cp;
// advance count of number of rooms
++roomcnt;
}
}
// add terminator to list
if (rooms != NULL)
rooms[roomcnt] = NULL;
fclose(fPointer); // close file
return rooms; // return pointer
}
P.S。不要心疼。无论程序员多么有经验,我们所有都会犯“愚蠢”的错误。而且,我们每隔日做。欢迎来到俱乐部!