目的:程序来洗牌文本文件的行
将文件读入数组
计数线和最大长度
计算数组的最大宽度
获取文件指针的开始
这些就是我在这个程序的第一部分要做的事情,来给你一些观点。 我不完全确定什么是“获取文件指针的开始”。 但是,我目前的问题是错误的读取行作为string数组。
更新了seg的代码。 当我去打印混洗arrays的错误。
#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 *
的数组而不是指向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
将保持lineCount
的大小。
在这种情况下,您可能需要将lineArray
声明为char **
并动态分配它:
lineArray = malloc(sizeof(char *)*lineCount);
然后,通过调用rewind(file);
来回到文件的开头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
。
lineArray
在这里只是一个字符指针,并且也是未初始化的。 它只会指向一个字节。 它必须是一个字符指针数组,如果它必须保存多行,那么lineArray[x]
或lineArray++
将带您到行数组中的下一行。
#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)