0

目的:程序来打乱文本文件的行

  • 将文件读入数组

  • 计数行和最大长度

  • 计算数组的最大宽度

  • 获取指向开头的文件指针

这些是我在程序的第一部分中尝试做的,以便为您提供一些观点。我不确定“将文件指针指向开头”是什么意思。但是,我当前的问题是将行作为字符串读入数组时出错。

更新了该段的代码。当我去打印洗牌数组时出现故障。

#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;
}
4

3 回答 3

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.

在这种情况下,您可能希望声明lineArraychar **并动态分配它:

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

于 2013-10-27T14:54:54.700 回答
0

lineArray在这里只是一个字符指针,而且未初始化。它只指向一个字节。如果它必须包含多行,则它必须是字符指针数组,以便lineArray[x]lineArray++将您带到行数组中的下一行。

于 2013-10-27T14:58:57.847 回答
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)

于 2013-10-27T15:13:43.363 回答