C 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 * имя_файла ; FILE * fp ; char * lines [ MAXSTACK ]; char * command ; int top = 0 ; int numlines = 0 ; if ( argc < 3 ) { fprintf ( stderr , "error: недостаточно аргументов n" ); выход ( 1 ); } filename = argv [ 1 ]; command = argv [ 2 ]; if ( ( fp = fopen ( filename , "r" )) == NULL ) { fprintf ( stderr , "ошибка: не удается открыть файл% s n" , имя файла ); выход ( 1 ); } else { for ( int i = 0 ; i < 3 ; i ++) { fscanf ( fp , "% s" , строки [ i ]); // printf ("% s n", строки [i]); } char ** ptr2 = строки ; for ( int i = 0 ; i < 2 ; i ++) { printf ( "% s n" , ptr2 [ i ]); } if ( strcmp ( команда , "pop" ) == 0 ) { // pop (lines); } else if ( strcmp ( команда , "print_top" ) == 0 ) { // print_top (); } else if ( strcmp ( command , "swap_top" ) == 0 ) { } } } из файла в указатель на массив символов с использованием fgets. При печати я получаю ошибки сегментации. Что я делаю не так? Должен ли я использовать функцию, отличную от fscanf?

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

c,scanf,

2

Ответов: 2


2 принят

Вы можете читать строки, используя 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++;lines

char *lines[MAXSTACK];

Обратите внимание, что когда вы пишете такой код:

MAXSTACK

вы выделяете в стек массив char*элементов, каждый из которых является freeуказателем. Но тогда вам нужно дать какое-то значимое значение этим указателям (например: выделение некоторой памяти из кучи и указание на эту память).

Конечно, когда вы закончите, вам нужно отсканировать весь массив и вызвать указатель на каждый элемент, чтобы избежать утечек памяти.memset(lines, 0, sizeof(lines));

Кроме того, хорошей практикой кодирования было бы очистить указатели в массиве перед его использованием, например:

fscanf("%s", lines[i])

1

lines[i]будет читать последовательность символов небелого пробела (обратите внимание, а не целую строку) в память, на которую указывает lines[i]. Проблема в том, что вы не char *lines[MAXSTACK];указали на какую-либо память, и именно поэтому вы получаете segfault, вы запрашиваете последовательность символов, которые нужно скопировать в какое-то неопределенное местоположение.

Если вы замените объявление массива указателей на символы char lines[MAXLENGTH][MAXSTACK], с объявлением массива массивов символов, lines[i]то MAXLENGTHэто будет массив fscanf("%s", lines[i])символов, MAXLENGTHкоторые можно копировать без seg-сбоев.

Вопрос остается в силе, что происходит, если строка fscanf пытается читать больше lines[MAXLENGTH]? Ответом будет больше символов, которые будут прочитаны, чем могут поместиться в fscanfмассив, и вы получите так называемое переполнение буфера. Чтобы защитить от этого, вы можете ограничить максимальное количество символов, которые fscanfбудут считываться из строки, например, до 100fscanf("%100s", lines[i])

с, зсапЕ,
Похожие вопросы