目的:程序来改变文本文件的行
将文件读入数组
计算行数和最大长度
计算数组的最大宽度
获取指向开头的文件指针
我正在尝试在程序的第一部分中为您提供一些观点。我不完全确定“获取文件指针到开头”是什么意思。但是,我当前的问题是将行读入数组作为字符串时出错。
更新了seg的代码。当我去打印洗牌阵列时出现故障。
#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;
}
答案 0 :(得分:0)
lineArray
应声明为char *
的数组,而不是指向char的指针:
char *lineArray[MAX_LINES];
另外,请考虑当您进入while
循环时会发生什么:您的代码具有未定义的行为,因为您正在访问从未初始化的lineArray[x]
,并且将包含垃圾值。
您应该使用fgets
将整行读入line
,然后将其复制到lineArray
。像这样:
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
,并且您希望首先读取整个文件以确定数组大小。为此,您可以使用类似的循环来首先计算行数,如下所示:
while (fgets(line, sizeof(line), file) != NULL) {
lineCount++;
}
在此循环之后,lineCount
将保留lineArray
的大小。
在这种情况下,您可能希望将lineArray
声明为char **
并动态分配:
lineArray = malloc(sizeof(char *)*lineCount);
然后,通过调用rewind(file);
返回文件的开头并执行将每行复制到lineArray
的循环。总之,您的代码看起来像:
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非常慢,而且你正在阅读它两次。考虑一下这是否真的是你想要的。也许一个好的方法是强制输入文件说明他们有多少行。
注2:您应该检查malloc()
的返回值。我没有在这个例子中这样做,但在现实世界中,请这样做。
注意3:最后,请记住free()
每个职位lineArray[i]
,然后免费lineArray
。
答案 1 :(得分:0)
lineArray
这里只是一个字符指针,太未初始化了。它只指向一个字节。它必须是一个字符指针数组,如果它必须包含多行,那么lineArray[x]
或lineArray++
会将你带到行数组的下一行。
答案 2 :(得分:0)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(int argc, char *argv[] ){
int x = 0, lineCount = 0, maxlen = 0;
char *lineArray[500], line[500];
FILE *file = fopen( argv[1], "r" );
if (file == NULL){
printf("Cannot open file\n");
exit(1);
}
while (x<500 && fgets(line,sizeof(line), file) ){
lineArray[x] = strdup(line);
if (strlen(line) > maxlen) {
maxlen = strlen(line);
}
x++;
lineCount++;
printf("%s\n", line);
}
printf("File %s has %d lines with maximum length of %d characters\n",
argv[1], lineCount, maxlen);
fclose(file);
return 0;
}
如果您想要查找此功能,请不要查看为什么需要回放文件,它是fseek(file,0,0)