c - 如何在 C 中浏览任意长度的字符串数组?

标签 c arrays string pointers gets

了解在 C 中处理直接指针

以下代码适用于固定数量项目和固定行长度的字符串数组:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNAMELEN 100
#define MAXLINELEN 100
#define MAXITEMS 1000

int main(int argc, char ** argv) {

 FILE * infile, * outfile;
 char name[MAXNAMELEN];
 char line[MAXLINELEN];
 char lines[MAXITEMS][MAXLINELEN];
 int i, items = 0;

 printf("Enter a source filename: ");
 fgets(name, sizeof(name), stdin);
 name[strlen(name)-1] = '\0'; // strip newline
 infile = fopen(name, "r");
 while (fgets(line, sizeof(line), infile)) {
        strcpy(lines[items], line);
        items++;
 }

 qsort(lines, items, MAXLINELEN, strcmp);

 printf("Enter a destination filename: ");
 fgets(name, sizeof(name), stdin);
 name[strlen(name)-1] = '\0'; // strip newline
 outfile = fopen(name, "w");
 for (i=0; i<items; i++) {
    fputs(lines[i], outfile);
 }

 fclose(infile);
 fclose(outfile);
}

问题描述和代码

如果我尝试读取 MAXLINELEN 内的 input.txt 文件和MAXITEMS ,程序运行良好。现在想象一下我正在逐行读取一个更大的“输入文件”,其中最大行长度可以是任何长度,那么我将不得不使用字符指针( char* )来读取输入。 char* linesptr[MAXITEMS];

这是我的代码,我试图在其中完成从由换行符分隔的输入文件逐行读取。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#define MAXNAMELEN 1000
#define MAXLINELEN 1000
#define MAXITEMS 100000

char* linesptr[MAXITEMS];

int
main(int argc, char ** argv) {

 FILE * infile, * outfile;
 char name[MAXNAMELEN];
 char line[MAXLINELEN];

 int i, items = 0;

 printf("Enter a source filename: ");
 fgets(name, MAXNAMELEN, stdin);
 name[strlen(name)-1] = '\0'; // strip newline
 printf("%s infile \n",name);
 infile = fopen(name, "r");
 while (fgets(line, MAXLINELEN, infile)) {
    int length = strlen(line);
    line[length-1] = '\0';
    linesptr[items] = line; *<- I am writing to the same mem location*
    printf("the input string %d is : %s \n",items,  linesptr[items]);
        items++;
 }

 qsort(linesptr, items, MAXLINELEN, strcmp); 
 printf("Enter a destination filename: ");
 fgets(name, sizeof(name), stdin);
 name[strlen(name)-1] = '\0'; // strip newline
 outfile = fopen(name, "w");
 for (i=0; i<items; i++) {
    fputs(linesptr[i], outfile);
 }

 fclose(infile);
 fclose(outfile);
}

问题

我正在将指针地址复制到数组的第 n 个单元格 linesptr其中 nth 是 value=items (以下是代码中的引用行: linesptr[items] = line; )。因此,当您打印最终答案时,我将相同的内存地址引用到名为 line 的缓冲区。 ,内存位置line将始终指向最新的 fgets() 。我了解该错误,但不知道如何解决该问题。我将不胜感激任何帮助修复代码中的错误。

最佳答案

将该行复制到动态分配的字符串。

while (fgets(line, MAXLINELEN, infile)) {
    int length = strlen(line);
    if (length > 0 && line[length-1] == '\n') {
        line[length-1] = '\0';
        length--;
    }
    char *linecopy = malloc(length+1);
    strcpy(linecpy, line);
    linesptr[items] = linecpy;
    printf("the input string %d is : %s \n",items,  linesptr[items]);
    items++;
}

如果您想要处理超过 MAXITEMS 行,则还应该使用 malloc() 分配 linesptr。当达到 linesptr 的当前大小时,您可以使用 realloc() 使其更长。请参阅Read unknown number of lines from stdin, C详细代码。

参见How to qsort an array of pointers to char in C?了解对字符串指针数组进行排序的正确方法。

关于c - 如何在 C 中浏览任意长度的字符串数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50997273/

相关文章:

arrays - 检查数组是否为空的最快方法

c - C中的Json解析和字符串管理

c - 为什么在 C 编程中需要 Fortran 包装器?

c++ - 如何在C/C++中模拟中断?

c++ - 二维数组中的指针运算

C++ 段错误

java - 开销与代码速度(java.io.File 数组与 java.lang.String 数组)

Lua 中的字符串操作 : Make the odd char uppercase

c - 从用户空间访问 i2c 扩展器的 GPIO 引脚

c - 写入和读取二进制文件时出现问题