将文件作为字符串逐行输入数组 [英] File input into array by line as string

查看:119
本文介绍了将文件作为字符串逐行输入数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目的:将文本文件的行重新排列的程序

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 * 的数组,而不是指向char的指针:

lineArray should be declared as an array of char * instead of a pointer to char:

char *lineArray[MAX_LINES];

另外,请考虑当您输入 while 循环:您的代码具有未定义的行为,因为您正在访问 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆