简体   繁体   English

C fscanf读取指向字符数组的指针

[英]C fscanf read pointer to array of characters

I am trying to read lines from a file into a pointer to a character array using fscanf. 我正在尝试使用fscanf将文件中的行读取到指向字符数组的指针中。 I am getting segmentation faults when I print. 打印时出现分段错误。 What am I doing wrong? 我究竟做错了什么? Should I be using a function other than fscanf? 我应该使用fscanf以外的功能吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stack.h"

#define MAXSTACK 100
#define MAXLENGHT 100

void main(int argc, char * argv[]){

  char *filename;
  FILE *fp;
  char *lines[MAXSTACK];
  char * command;
  int top = 0;
  int numlines = 0;

  if(argc < 3){

    fprintf(stderr,"error: Not enough arguments provided\n");
    exit(1);
  }

  filename = argv[1];
  command = argv[2];

  if ( (fp = fopen(filename,"r")) == NULL ){

    fprintf(stderr,"error: Cannot open file %s\n",filename);
    exit(1);
  }
  else{

    for(int i = 0; i < 3; i++){

        fscanf(fp,"%s",lines[i]);
    //    printf("%s\n",lines[i]);
    }

    char **ptr2 = lines;
    for (int i = 0; i < 2; i++){

         printf("%s\n", ptr2[i]);
    }

    if (strcmp(command,"pop")==0){

      //pop(lines);
     }else if (strcmp(command,"print_top")==0){
      //print_top();

    }else if(strcmp(command,"swap_top")==0){

    }
   }
} 

You may want to read lines using fgets : 您可能想使用fgets读取行:

/* Read a single line into a temporary buffer */
char lineBuffer[MAX_LINE_LENGTH];
while (fgets(lineBuffer, sizeof(lineBuffer), fp) != NULL) {
    /* Process the read line */
}

Once you have read a line in the temporary buffer, you can deep-copy the read string into some memory that you allocated on the heap using malloc (or you can just use strdup ), and then you can store a pointer to that memory into your lines array: 读取临时缓冲区中的一行后,可以使用malloc将读取的字符串深度复制到您在堆上分配的某些内存中(或者您可以仅使用strdup ),然后可以将指向该内存的指针存储到您的lines数组:

 /* Inside the body of the while loop */

 /* 
  * Deep copy current line into the string pointer array.
  * strdup = malloc + strcpy
  * Note that free is required to release memory!
  */
 lines[currLineIndex] = strdup(lineBuffer);

 currLineIndex++;

Note that when you write code like this: 请注意,当您编写如下代码时:

 char *lines[MAXSTACK]; 

you are allocating on the stack an array of MAXSTACK items, each item being a char* pointer. 您正在堆栈上分配一个MAXSTACK项目数组,每个项目都是一个char*指针。 But then you have to give some meaningful value to those pointers (for example: allocating some memory from the heap and pointing to that memory). 但是然后您必须为这些指针赋予一些有意义的值(例如:从堆中分配一些内存并指向该内存)。

Of course, when you are done, you have to scan the whole array and call free on each element pointer to avoid memory leaks. 当然,完成后,您必须扫描整个数组并在每个元素指针上调用free ,以避免内存泄漏。

Moreover, a good coding practice would be to clear the pointers in the array before using it, eg: 此外,一种良好的编码习惯是在使用数组之前清除数组中的指针,例如:

memset(lines, 0, sizeof(lines));

fscanf("%s", lines[i]) will read a sequence of non-white-space characters (note, not a whole line) into the memory pointed to by lines[i] . fscanf("%s", lines[i])将读取一系列非空白字符(注意,不是整行)到由lines[i]指向的内存中。 The problem is, that you haven't set lines[i] to point to any memory and that is why you get the segfault, you're asking for a sequence of characters to be copied to some undefined location. 问题是,您没有设置lines[i]指向任何内存,这就是为什么出现段错误的原因,您要求将字符序列复制到某个未定义的位置。

If you replace your declaration of an array of character pointers, char *lines[MAXSTACK]; 如果替换了字符指针数组的声明,则char *lines[MAXSTACK]; , with a declaration of an array of arrays of characters char lines[MAXLENGTH][MAXSTACK] then lines[i] will be an array of MAXLENGTH characters which fscanf("%s", lines[i]) which be able to copy to without seg faulting. ,声明了字符数组char lines[MAXLENGTH][MAXSTACK]的数组,则lines[i]将是MAXLENGTH字符的数组,其中fscanf("%s", lines[i])可以复制到没有段错误。

The question remains now, what happens if the string fscanf tries to read is longer than MAXLENGTH ? 现在的问题仍然存在,如果字符串fscanf尝试读取的长度超过MAXLENGTH什么? The answer is more characters will be read than can fit into the lines[MAXLENGTH] array and you get what is called a buffer overflow. 答案是,将读取的字符超出了可容纳到lines[MAXLENGTH]数组中的lines[MAXLENGTH] ,您将得到所谓的缓冲区溢出。 To safeguard against this you can limit the maximum number of characters fscanf will read from a string, to 100 for example, with fscanf("%100s", lines[i]) 为了防止这种情况,可以使用fscanf("%100s", lines[i])fscanf从字符串读取的最大字符数限制为例如100个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM