c - 在 C 中用 gets 读取一个 txt 文件

标签 c arrays gets

我想知道使用 c 中的 gets 函数读取包含两行数字的 txt 文件并在 1 秒内将它们保存在数组中的最佳选择是什么。

假设下面的例子是一个名为 ooo.txt 的 txt 文件,它的第一行有数字 2.000.000(这将是数组的大小),第二行有 2.000.000 数字将被存储在数组中。

例如

2000000
59 595 45 492 89289 5 8959 (+1.999.993 numbers)

我尝试的代码(仅 fcanf 函数)

int t_size;
fscanf(fp, "%d",&t_size);  //bypass the first character!




        int* my_array = NULL; 
        my_array = malloc(t_size*sizeof(*my_array));


        if (my_array==NULL) {
        printf("Error allocating memory!\n"); //print an error message
        return 1; //return with failure
        getchar();
        }

        int i =0;
        for ( i = 0; i < t_size; i++ )
        {
        fscanf(fp, "%d",&my_array[i]);  /*p[i] is the content of element at index i and &p[i] is the address of element at index i */
        }

到目前为止,在 1 秒内完成该过程的最佳代码

 #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    #include <time.h>

    int is_end(char* input) {
        return *input == 0;
    }

    int is_linebreak(char* input) {
        return *input == '\r' || *input == '\n' || *input == ' ';
    }

    char* eat_linebreaks(char* input) {
        while (is_linebreak(input))
            ++input;

        return input;
    }

    size_t count_lines(char* input) {
        char* p = input;
        size_t rows = 1;

        if (is_end(p))
            return 0;

        while (!is_end(p)) {
            if (is_linebreak(p)) {
                ++rows;
                p = eat_linebreaks(p);
            }
            else {
                ++p;
            }
        }
        return rows;
    }

    /* split string by lines */
    char** get_lines(char* input, size_t line_count) {
        char* p = input;
        char* from = input;
        size_t length = 0;
        size_t line = 0;
            int i;
        char** lines = (char**)malloc(line_count * sizeof(char*));

        do {
            if (is_end(p) || is_linebreak(p)) {
                lines[line] = (char*)malloc(length + 1);
                for (i = 0; i < length; ++i)
                    lines[line][i] = *(from + i);

                lines[line][length] = 0;
                length = 0;
                ++line;
                p = eat_linebreaks(p);
                from = p;

            }
            else {
                ++length;
                ++p;
            }
        } while (!is_end(p));

        // Copy the last line as well in case the input doesn't end in line-break
        lines[line] = (char*)malloc(length + 1);
        for (i = 0; i < length; ++i)
            lines[line][i] = *(from + i);

        lines[line][length] = 0;
        ++line;


        return lines;
    }

    int main(int argc, char* argv[]) {
        clock_t start;
        unsigned long microseconds;
        float seconds;
        char** lines;
        size_t size;
        size_t number_of_rows;
        int count;
        int* my_array;
        start = clock();

        FILE *stream;
        char *contents;
        int fileSize = 0;
            int i;

        // Open file, find the size of it
        stream = fopen(argv[1], "rb");
        fseek(stream, 0L, SEEK_END);
        fileSize = ftell(stream);
        fseek(stream, 0L, SEEK_SET);

        // Allocate space for the entire file content
        contents = (char*)malloc(fileSize + 1);

        // Stream file into memory
        size = fread(contents, 1, fileSize, stream);
        contents[size] = 0; 
        fclose(stream);

        // Count rows in content
        number_of_rows = count_lines(contents);

        // Get array of char*, one for each line
        lines = get_lines(contents, number_of_rows);

        // Get the numbers out of the lines
        count = atoi(lines[0]); // First row has count
        my_array = (int*)malloc(count * sizeof(int));
        for (i = 0; i < count; ++i) {
            my_array[i] = atoi(lines[i + 1]);
        }

        microseconds = clock() - start;
        seconds = microseconds / 1000000.0f;
        printf("Took %fs", seconds);


        return 0;
    }

最佳答案

首先,您需要使用 fgets 来避免危险的缓冲区溢出。其次,您想从数字中删除所有标点符号。这样 2.000.000 就变成了 2000000。然后你可以使用指针和 strtol 函数将字符转换为整数;还有其他函数可以转换为 float 和其他类型。

关于c - 在 C 中用 gets 读取一个 txt 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27296441/

相关文章:

c++ - 将数组大小减少到 1 的最小成本

c - 替换已弃用的 gets()

c - 字段的 __attribute__((packed)) 如何影响包含该字段的结构?

C 内存分配(malloc)

c - 在 C 中访问二维数组的元素

c - 这个 "make a triangle loop"循环超过必要时间的任何原因

c - while循环在C中获取()两次

c - 在gets之前输入C.scanf。问题

java - 如何在 OSGI 包中包含 C 代码

c - 激活记录长度