将文件作为字符串逐行输入数组 [英] File input into array by line as string
问题描述
目的:将文本文件的行重新排列的程序
Purpose: program to shuffle the lines of a text file
-
将文件读入数组
Read the file into an array
计算行数和最大长度
计算数组的最大宽度
获取指向开头的文件指针
Get file pointer to the beginning
这些是我要尝试的在程序的第一部分中做的工作可以给您一些视角。我不确定从头开始获取文件指针是什么意思。但是,我当前的问题是将行作为字符串读取到数组中时出错。
These are what I'm trying to do in the first part of the program to give you some perspective. I'm not exactly sure what is meant by "Get file pointer to the beginning". However, my current problem is error reading the lines into an array as strings.
更新了段代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// Accepts: command line input
// Returns: 0 if no error
int main(int argc, char *argv[] ){
int x = 0, i, lineCount = 0, maxLen = 0;
char line[500], temp;
FILE *file = fopen( argv[1], "r" );
// check if file exists
if (file == NULL){
printf("Cannot open file\n");
return 1;
}
// Gets lines, max length of string
while (fgets(line, sizeof(line), file) != NULL){
lineCount++;
if (strlen(line) > maxLen)
maxLen = strlen(line);
}
rewind(file);
char *lineArray[lineCount];
while (fgets(line, sizeof(line), file) != NULL) {
lineArray[x] = malloc(strlen(line));
if (lineArray[x] == NULL){
printf("A memory error occurred.\n");
return(1);
}
strcpy(lineArray[x], line);
// change \n to \0
lineArray[x][strlen(lineArray[x])-1] = '\0';
x++;
}
printf("File %s has %d lines with maximum length of %d characters\n",
argv[1], lineCount, maxLen);
printf("Original Array\n");
for (x = 0; x < lineCount; x++)
printf("%2d %s\n", x, lineArray[x]);
// Shuffle array
srand( (unsigned int) time(NULL));
for (x = lineCount - 1; x >= 0; x--){
i = (int) rand() % lineCount;
temp = lineArray[x];
lineArray[x] = lineArray[i];
lineArray[i] = temp;
}
printf("\nShuffled Array\n");
for (x = 0; x < lineCount; x++)
printf("%2d %s\n", x, lineArray[x]);
// free allocated memory
for (x = 0; x < lineCount; x++)
free(lineArray[x]);
free(lineArray);
fclose(file);
return 0;
}
推荐答案
lineArray
应该声明为 char * $code>的数组,而不是指向char的指针:
lineArray
should be declared as an array of char *
instead of a pointer to char:
char *lineArray[MAX_LINES];
另外,请考虑当您输入 while $ c $时会发生什么c>循环:您的代码具有未定义的行为,因为您正在访问
lineArray [x]
,该代码从未初始化,并且将包含垃圾值。
Also, consider what happens when you enter the while
loop: your code has undefined behavior, because you are accessing lineArray[x]
, which was never initialized, and will contain garbage values.
您应该使用 fgets
代替,将整行读入 line
,然后复制放入 lineArray
。像这样的东西:
You should use fgets
instead to read a whole line into line
, and then copy it into lineArray
. Something like this:
while (fgets(line, sizeof(line), file) != NULL) {
lineCount++;
lineArray[x] = malloc(strlen(line));
strcpy(lineArray[x], line);
printf("%s\n", lineArray[x]);
x++;
}
从您的帖子中看来,您不想局限于 MAX_LINES
,您想先读取整个文件以确定数组大小。为此,您可以使用类似的循环先计算行数,如下所示:
From your post, it appears that you don't want to be limited to MAX_LINES
, and you want to read the whole file first to determine the array size. To do so, you can use a similar loop to count the number of lines first, like this:
while (fgets(line, sizeof(line), file) != NULL) {
lineCount++;
}
此循环后, lineCount
将保留 lineArray
的大小。
After this loop, lineCount
will hold the size for lineArray
.
在这种情况下,您可能需要将 lineArray
声明为 char **
并动态分配:
In this case, you may want to declare lineArray
as char **
and allocate it dynamically:
lineArray = malloc(sizeof(char *)*lineCount);
然后,通过调用 rewind(file );
并执行将每行复制到 lineArray
的循环。总之,您的代码如下所示:
Then, get back to the beginning of the file by calling rewind(file);
and execute the loop that copies each line into lineArray
. In summary, your code would look something like:
while (fgets(line, sizeof(line), file) != NULL) {
lineCount++;
}
lineArray = malloc(sizeof(char *)*lineCount);
rewind(file);
while (fgets(line, sizeof(line), file) != NULL) {
lineArray[x] = malloc(strlen(line));
strcpy(lineArray[x], line);
printf("%s\n", lineArray[x]);
x++;
}
注1:效率低下。文件I / O非常慢,您正在读取两次。考虑这是否真的是您想要的方式。也许一个好的方法是强制输入文件说出它们有多少行。
Note 1: This is inefficient. File I/O is extremely slow, and you're reading it twice. Consider if this is really how you want to do it. Maybe a good approach would be to force input files to say how many lines they have.
注2:您应该检查 malloc()
的返回值。在此示例中我没有这样做,但是在现实世界中,请这样做。
Note 2: You should check malloc()
's return value. I didn't do it in this example, but in real world, please do it.
注3:最后,请记住免费 ()
每个位置 lineArray [i]
,然后免费提供 lineArray
。
Note 3 : In the end, remember to free()
every position lineArray[i]
, and after that, free lineArray
.
这篇关于将文件作为字符串逐行输入数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!