[英]Reading a text file into 2 separate arrays of characters (in C)
对于一堂课,我必须编写一个程序来读取文本文件,格式为:
TAEDQQ
ZHPNIU
凯迪
VUXOFC
毕马威
NRTBRB
出口
的
快
棕色
狐狸
我正在尝试将字符放入一个char数组中,每一行都是其自己的数组。 我可以从文件中读取,这是我用来解析文件的代码:
char** getLinesInFile(char *filepath)
{
FILE *file;
const char mode = 'r';
file = fopen(filepath, &mode);
char **textInFile;
/* Reads the number of lines in the file. */
int numLines = 0;
char charRead = fgetc(file);
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
numLines++;
}
charRead = fgetc(file);
}
fseek(file, 0L, SEEK_SET);
textInFile = (char**) malloc(sizeof(char*) * numLines);
/* Sizes the array of text lines. */
int line = 0;
int numChars = 1;
charRead = fgetc(file);
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
textInFile[line] = (char*) malloc(sizeof(char) * numChars);
line++;
numChars = 0;
}
else if(charRead != ' ')
{
numChars++;
}
charRead = fgetc(file);
}
/* Fill the array with the characters */
fseek(file, 0L, SEEK_SET);
charRead = fgetc(file);
line = 0;
int charNumber = 0;
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
line++;
charNumber = 0;
}
else if(charRead != ' ')
{
textInFile[line][charNumber] = charRead;
charNumber++;
}
charRead = fgetc(file);
}
return textInFile;
}
这是我程序的运行:
欢迎使用Word搜索!
输入您希望我们解析的文件:testFile.txt TAEDQQ!ZHPNIU!CKEWDI!VUXOFC!BPIRGK!NRTBRB!EXIT!QUICK!BROWN!FOX分段错误
这是怎么回事? A),为什么会有感叹号?B)为什么最后我出现段错误? 我主要要做的最后一件事是遍历数组/指针。
1)在程序的第一部分中,您误算了文件中的行数。 文件中的实际行数为11,但是您的程序为10。您需要从1开始计数,因为文件中始终至少有一行。 所以改变
int numLines = 0;
至
int numLines = 1;
2)在程序的第二部分中,您误算了每行中的字符数。 您需要保持计数器初始化不变。 在该段的开头,将numChars初始化为1。在这种情况下,您需要在每次迭代后将计数器重置为1,因此请更改:
numChars = 0;
至
numChars = 1;
这应该为所有非空格字符和结尾的NULL终止符提供足够的空间。 请记住,在C char *中,字符串始终以NULL终止。
3)您的程序也没有考虑行终止的差异,但是在我的测试环境下这没有问题-即使文件使用\\ r \\ n终止符保存,fgetc仍仅为行终止符返回一个字符。
4)在程序的第二部分,您也没有为最后一行分配内存。 当您尝试访问未分配的空间时,这会导致程序第三部分出现段错误。
请注意,您的代码仅在行以\\ r或\\ n结尾时才保存行。 猜猜是什么,EOF从技术上讲是最后一行的结尾,不符合条件。 因此,第二个循环不会将最后一行保存到数组中。
要解决此问题,请在第二部分之后添加:textInFile [line] =(char *)malloc(sizeof(char)* numChars);
4)在程序输出中,您会看到那些奇怪的感叹号,因为您不能以NULL终止字符串。 因此,您需要在下面添加标记为NULL终止的行:
if(charRead == '\n' || charRead == '\r')
{
textInFile[line][charNumber] = 0; // NULL termination
line++;
charNumber = 0;
}
5)由于您正在检查EOF,因此在第三个循环中存在相同的问题,因此必须在返回之前将其添加
textInFile[line][charNumber] = 0; // NULL termination
6)由于整个程序的结构,我也有些头疼。 您逐字符读取同一文件3次! 这是极其缓慢且效率低下的。
固定代码如下:
char** getLinesInFile(char *filepath)
{
FILE *file;
const char mode = 'r';
file = fopen(filepath, &mode);
char **textInFile;
/* Reads the number of lines in the file. */
int numLines = 1;
char charRead = fgetc(file);
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
numLines++;
}
charRead = fgetc(file);
}
fseek(file, 0L, SEEK_SET);
textInFile = (char**) malloc(sizeof(char*) * numLines);
/* Sizes the array of text lines. */
int line = 0;
int numChars = 1;
charRead = fgetc(file);
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
textInFile[line] = (char*) malloc(sizeof(char) * numChars);
line++;
numChars = 1;
}
else if(charRead != ' ')
{
numChars++;
}
charRead = fgetc(file);
}
textInFile[line] = (char*) malloc(sizeof(char) * numChars);
/* Fill the array with the characters */
fseek(file, 0L, SEEK_SET);
charRead = fgetc(file);
line = 0;
int charNumber = 0;
while (charRead != EOF)
{
if(charRead == '\n' || charRead == '\r')
{
textInFile[line][charNumber] = 0; // NULL termination
line++;
charNumber = 0;
}
else if(charRead != ' ')
{
textInFile[line][charNumber] = charRead;
charNumber++;
}
charRead = fgetc(file);
}
textInFile[line][charNumber] = 0; // NULL termination
return textInFile;
}
终止数组不是空的。 这可能解释了两个问题。 确保为空终止符分配一个额外的字符。
做这个:
if(charRead == '\n')
{
textInFile[line] = (char*) malloc(sizeof(char) * (numChars+1));
line++;
numChars = 0;
}
然后:
if(charRead == '\n')
{
textInFile[line][charNumber]='\0';
line++;
charNumber = 0;
}
另外,您正在读取文件3次! 该线程对如何有效读取文件有一些很好的解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.