简体   繁体   中英

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. I am getting segmentation faults when I print. What am I doing wrong? Should I be using a function other than 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 :

/* 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:

 /* 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. 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.

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] . 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.

If you replace your declaration of an array of character pointers, 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.

The question remains now, what happens if the string fscanf tries to read is longer than 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. 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])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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