将文件作为字符串逐行输入到数组中

时间:2013-10-27 14:46:04

标签: c arrays linux file

目的:程序来改变文本文件的行

  • 将文件读入数组

  • 计算行数和最大长度

  • 计算数组的最大宽度

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

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

更新了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;
}

3 个答案:

答案 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)